У меня вопрос об эффективности 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, если в одном билете есть один или несколько бонусных шаров. Для меня этого достаточно.
Спасибо за помощь