Проверка выигрышных билетов в лотерее с помощью SQL

У меня вопрос об эффективности SQL. Это касается норвежской национальной лотереи. Они тянут семь чисел и три бонусных шара.

У меня есть база данных со всеми рисунками и множеством билетов. Вопрос в том, какова наиболее эффективная структура стола и способ получить все выигрышные билеты в розыгрыше.

Это две мои основные таблицы:

LotteryDraw
   DrawId (int, PK)
   DrawDate (datetime)
   MainNumbers (varchar)
   BonusNumbers (varchar)
   Main1 (smallint)
   Main2 (smallint)
   Main3 (smallint)
   Main4 (smallint)
   Main5 (smallint)
   Main6 (smallint)
   Main7 (smallint)
   Bonus1 (smallint)
   Bonus2 (smallint)
   Bonus3 (smallint)

Я храню каждое из основных и бонусных номеров отдельно, а также строка, разделенная запятыми, в отсортированном порядке.

У меня аналогично:

LotteryTicket
   TicketId (int, PK)
   UserId (int, FK)
   ValidTill (datetime)
   MainNumbers (varchar)
   Main1 (smallint)
   Main2 (smallint)
   Main3 (smallint)
   Main4 (smallint)
   Main5 (smallint)
   Main6 (smallint)
   Main7 (smallint)

Вы получаете призы за 4 + 1, 5, 6, 6 + 1 и 7 правильных чисел (правильные основные числа + бонусные числа). У кого-нибудь есть отличные идеи о том, как написать эффективный SQL, который вернет все LotteryTickets с призом на дату розыгрыша? ValidTill - это дата последнего розыгрыша, когда билет был действителен.

Моя текущая попытка использовать Linq2Sql на C # и имеет скорость бегемота на льду, поэтому мне действительно нужны некоторые знания SQL.

Сервер - Microsoft SQL Server 2008 R2, если это имеет значение.

Обновление: после настройки ответ от Марка Б. В итоге я получил следующий вопрос. Мне нужно было немного нормализовать базу данных, добавив новую таблицу LotteryTicketNumber (ticketid, number).

SELECT LotteryTicket.TicketID, count(LotteryTicket.Numbers) AS MainBalls, (
    SELECT top 1 ltn.Number
    FROM LotteryTicketNumber ltn
    WHERE ltn.Number IN (2,4,6)
    AND ltn.TicketId = LotteryTicket.TicketId
) As BonusBall
FROM LotteryTicket
LEFT JOIN LotteryTicketNumber ON LotteryTicket.TicketId = LotteryTicketNumber.TicketId
WHERE LotteryTicketNumber.Number IN (13,14,16,23,26,27,30)
GROUP BY LotteryTicket.TicketID
HAVING count(LotteryTicketNumber.Number) >= 4

Вышеупомянутый запрос возвращает все билеты с как минимум 4 правильными основными номерами. Также поле Bonusball! = NULL, если в одном билете есть один или несколько бонусных шаров. Для меня этого достаточно.

Спасибо за помощь

5
задан Paaland 29 March 2011 в 18:32
поделиться