Используйте левое значение в сравнении SQL с правым
-
22-09-2019 - |
Вопрос
У меня есть это SELECT
заявление:
SELECT SUM(dbo.DLData.Quantity)
FROM dbo.MasterDates
JOIN dbo.DLData ON MasterDates.[ID] = dbo.DLData.DownloadID
WHERE dbo.MasterDates.[Date] BETWEEN @From AND @To
AND dbo.MasterDates.SiteID = @X
Если вы подключите @From
, @To
и @X
это работает.Это должно быть правильной стороной сравнения.Однако при сравнении @X
должно исходить с левой стороны, поскольку SELECT
снаружи выполняется тест на каждом SiteID
в наборе.Без этого пункта работает основное предложение.Они должны идти вместе.Вот полная инструкция select, в которой оставлен приведенный выше пункт select.В конечном счете два пункта having будут определять ключевые продукты для сайта.
--INSERT INTO SiteKeyProducts
SELECT dbo.MasterDates.SiteID as SiteID , dbo.DLData.Product as ProductID
FROM dbo.MasterDates
JOIN dbo.DLData ON dbo.MasterDates.[ID] = dbo.DLData.DownloadID
WHERE dbo.MasterDates.[Date] BETWEEN @From AND @To
GROUP BY dbo.MasterDates.SiteID , dbo.DLData.Product
HAVING
SUM(dbo.DLData.Quantity) > 960 OR
SUM(dbo.DLData.Quantity) > (SELECT SUM(dbo.DLData.Quantity)
FROM dbo.MasterDates
JOIN dbo.DLData ON MasterDates.[ID] = dbo.DLData.DownloadID
WHERE dbo.MasterDates.[Date] BETWEEN @From AND @To
AND dbo.MasterDates.SiteID = @X)
ORDER BY dbo.MasterDates.SiteID
Как вы используете внешнее предложение во внутреннем операторе? Черт возьми, я даже не знаю, использую ли я правильную терминологию для описания моей проблемы.
Arrgghh - Логика, основанная на множестве, сводит меня с ума!!
Решение 2
Мэтт Уитфилд на ask.sqlserverцентральный Сайт StackExchange выдал следующий ответ на эта проблема:
SELECT outerMaster.SiteID as SiteID , dbo.DLData.Product as ProductID
FROM dbo.MasterDates outerMaster
JOIN dbo.DLData ON outerMaster.[ID] = dbo.DLData.DownloadID
WHERE outerMaster.[Date] BETWEEN @From AND @To
GROUP BY outerMaster.SiteID , dbo.DLData.Product
HAVING
SUM(dbo.DLData.Quantity) > 960 OR
SUM(dbo.DLData.Quantity) > (SELECT SUM(dbo.DLData.Quantity)
FROM dbo.MasterDates innerMaster
JOIN dbo.DLData ON innerMaster.[ID] = dbo.DLData.DownloadID
WHERE innerMaster.[Date] BETWEEN @From AND @To
AND innerMaster.SiteID = outerMaster.SiteID)
ORDER BY outerMaster.SiteID
И Рикд придумал этот ответ на ask.sqlteam.com Сайт:
--INSERT INTO SiteKeyProducts
SELECT
MD.SiteID as SiteID ,
DLD.Product as ProductID
FROM dbo.MasterDates MD
JOIN dbo.DLData DLD
ON MD.[ID] = DLD.DownloadID
LEFT JOIN (SELECT SiteID,
SUM(dbo.DLData.Quantity) SumMDQuantity
FROM dbo.MasterDates
JOIN dbo.DLData ON MasterDates.[ID] = dbo.DLData.DownloadID
WHERE dbo.MasterDates.[Date] BETWEEN @From AND @To
GROUP BY SiteID) as sumMD
ON sumMD.SiteID = MD.SiteID
WHERE MD.[Date] BETWEEN @From AND @To
GROUP BY MD.SiteID , DLD.Product
HAVING
SUM(DLD.Quantity) > 960 OR
SUM(DLD.Quantity) > sumMD.SumMDQuantity
ORDER BY MD.SiteID
Оба работают отлично, хотя Мэттс превосходит усилия Рика, несмотря на мое первоначальное мнение, что объединение было бы быстрее.Маттс занимает ~ 2 м 10 секунд, в то время как Рикс занимает ~ 2 м 40 секунд.Это для самой большой действующей базы данных, поскольку и то, и другое занимает менее 10 секунд в тестовой базе данных.
Другие советы
Я думаю, вы хотите присоединиться к этому подзапросу, а не использовать его в операторе having
SELECT SUM(dbo.DLData.Quantity)
FROM dbo.MasterDates
JOIN dbo.DLData ON MasterDates.[ID] = dbo.DLData.DownloadID
WHERE dbo.MasterDates.[Date] BETWEEN @From AND @To
AND dbo.MasterDates.SiteID = @X