У меня есть запрос, который я пишу. Он собирает некоторые данные из нескольких разных таблиц, а также вычисляет сумму и некоторые средние значения.
Первоначально, мой клиент попросил меня выбрать на основе определенных критериев, ограничивая из общего списка частей, однако теперь клиент хочет иметь возможность показать все элементы, даже если они не попадают в критерии.
Проблема, с которой я сталкиваюсь, заключается в том, что мой первоначальный запрос, очевидно, ограничивает выбор, потому что для определения определенных критериев необходимо использовать предложение where (например, в зависимости от категории, оно включает результаты только тогда, когда они отрицательные, но не положительные), и при попытке использовать объединение я получаю дубликат записи каждый раз, когда что-то попадает в критерии. Это означает, что мой второй Select получает все, но он не отфильтровывает эту запись, когда она уже была добавлена из первой. Union не считает, что они различны, так как рассчитанные поля отличаются, даже если номер детали совпадает.
Я попытался создать обратный набор условий Где, который просто получит зеркальное отражение первоначального выбора, исключив тем самым возможность дублирования, однако я не могу найти правильные критерии.
Могу ли я получить помощь в создании противоположного выбора для следующего набора условий Где (два параметра деления должны быть одинаковыми для обоих, но создание обратного набора условий для других может работать, я просто не могу разберись как):
WHERE(iitt.Name = 'Invoicing'
OR iitt.Name = 'Issuing'
OR (iitt.Name = 'Post Worksheet'
AND iit.quantity <= 0))
AND iit.TransactionDate BETWEEN @StartDate AND @EndDate
AND id.DivisionFK = @division
AND iit.DivisionNumber = @division
Или какой-то другой метод, позволяющий четко выбирать на основе совпадения только в определенном поле объединения, а не идентичное совпадение для каждого поля, являющееся единственным критерием, по которому фильтрация результатов объединяет результаты? Выберите Distinct или Top 1 не работает. Полный код ниже:
DECLARE @startdate DATE, @enddate DATE, @division INT;
SET @startdate = '5/23/2018';
SET @enddate = '6/26/2018';
SET @division = 2;
SELECT i.PartNumber AS 'Part Number',
CONVERT(DOUBLE PRECISION, CAST(ABS(SUM(iit.quantity)) AS DECIMAL(19, 0))) AS 'Sum Quantity',
CONVERT(DOUBLE PRECISION, id.quantityOnHand) AS 'Division Quantity on Hand',
CASE
WHEN SUM(iit.quantity) = 0
THEN 0
WHEN DATEPART(DAYOFYEAR, @enddate) - DATEPART(DAYOFYEAR, @startdate) = 0
THEN 0
WHEN YEAR(@enddate) - YEAR(@startdate) = 1
THEN CONVERT(DOUBLE PRECISION, CAST(ABS((SUM(iit.quantity) / ((364 - DATEPART(DAYOFYEAR, @startdate)) + DATEPART(DAYOFYEAR, @enddate)))) AS DECIMAL(19, 2)))
WHEN YEAR(@enddate) - YEAR(@startdate) = 2
THEN CONVERT(DOUBLE PRECISION, CAST(ABS(SUM(iit.quantity) / ((364 - DATEPART(DAYOFYEAR, @startdate)) + DATEPART(DAYOFYEAR, @enddate) + 364)) AS DECIMAL(19, 2)))
ELSE CONVERT(DOUBLE PRECISION, CAST(ABS(SUM(iit.quantity) / (DATEPART(DAYOFYEAR, @enddate) - DATEPART(DAYOFYEAR, @startdate))) AS DECIMAL(19, 2)))
END AS 'Avg Use Per Day',
CASE
WHEN SUM(iit.quantity) = 0
THEN NULL
WHEN SUM(iit.quantity) / ((364 - DATEPART(DAYOFYEAR, @startdate)) + DATEPART(DAYOFYEAR, @enddate)) = 0
THEN 0
WHEN SUM(iit.quantity) / ((364 - DATEPART(DAYOFYEAR, @startdate)) + DATEPART(DAYOFYEAR, @enddate) + 364) = 0
THEN 0
WHEN SUM(iit.quantity) / ((364 - DATEPART(DAYOFYEAR, @startdate)) + DATEPART(DAYOFYEAR, @enddate) + 364) = 0
THEN 0
WHEN SUM(iit.quantity) / (DATEPART(DAYOFYEAR, @enddate) - DATEPART(DAYOFYEAR, @startdate)) = 0
THEN 0
WHEN YEAR(@enddate) - YEAR(@startdate) = 1
THEN CONVERT(DOUBLE PRECISION, CAST(ABS(ROUND(id.quantityOnHand / ((SUM(iit.quantity) / ((364 - DATEPART(DAYOFYEAR, @startdate)) + DATEPART(DAYOFYEAR, @enddate)))), 2)) AS DECIMAL(19, 2)))
WHEN YEAR(@enddate) - YEAR(@startdate) = 2
THEN CONVERT(DOUBLE PRECISION, CAST(ABS(ROUND(id.quantityOnHand / (SUM(iit.quantity) / ((364 - DATEPART(DAYOFYEAR, @startdate)) + DATEPART(DAYOFYEAR, @enddate) + 364)), 2)) AS DECIMAL(19, 2)))
ELSE CONVERT(DOUBLE PRECISION, CAST(ABS(ROUND(id.quantityOnHand / (SUM(iit.quantity) / (DATEPART(DAYOFYEAR, @enddate) - DATEPART(DAYOFYEAR, @startdate))), 2)) AS DECIMAL(19, 2)))
END AS 'Depletion Days per Avg Use',
CONVERT(DOUBLE PRECISION, CAST(ROUND(ii.StandardCost, 3) AS DECIMAL(19, 3))) AS 'Standard Cost'
FROM Item i
INNER JOIN ItemInventoryTransaction iit ON i.itempk = iit.itemfk
INNER JOIN ItemInventoryTransactionType iitt ON iitt.ItemInventoryTransactionTypePK = iit.ItemInventoryTransactionTypeFK
INNER JOIN ItemInventory ii ON i.ItemInventoryFK = ii.ItemInventoryPK
INNER JOIN ItemDivision id ON i.ItemPK = id.ItemFK
INNER JOIN Division d ON id.DivisionFK = d.DivisionPK
WHERE(iitt.Name = 'Invoicing'
OR iitt.Name = 'Issuing'
OR (iitt.Name = 'Post Worksheet' AND iit.quantity <= 0))
AND iit.TransactionDate BETWEEN @StartDate AND @EndDate
AND id.DivisionFK = @division
AND iit.DivisionNumber = @division
GROUP BY i.PartNumber,
id.quantityOnHand,
ii.StandardCost
UNION
SELECT i.PartNumber AS 'Part Number',
NULL AS 'Sum Quantity',
CONVERT(DOUBLE PRECISION, id.quantityOnHand) AS 'Division Quantity on Hand',
NULL AS 'Avg Use Per Day',
NULL AS 'Depletion Days per Avg Use',
CONVERT(DOUBLE PRECISION, CAST(ROUND(ii.StandardCost, 3) AS DECIMAL(19, 3))) AS 'Standard Cost'
FROM Item i
INNER JOIN ItemInventoryTransaction iit ON i.itempk = iit.itemfk
INNER JOIN ItemInventoryTransactionType iitt ON iitt.ItemInventoryTransactionTypePK = iit.ItemInventoryTransactionTypeFK
INNER JOIN ItemInventory ii ON i.ItemInventoryFK = ii.ItemInventoryPK
INNER JOIN ItemDivision id ON i.ItemPK = id.ItemFK
INNER JOIN Division d ON id.DivisionFK = d.DivisionPK
WHERE id.DivisionFK = @division
AND iit.DivisionNumber = @division
ORDER BY [Part Number];