#sql-server
#sql-сервер
Вопрос:
Используемый код:
SELECT
ROUND(SUM(COALESCE(p.[Weight], 0)), 2) AS [Total weight]
FROM
SalesLT.SalesOrderHeader soh
JOIN
SalesLT.SalesOrderDetail sod ON sod.SalesOrderID = soh.SalesOrderID
JOIN
SalesLT.Product p ON p.ProductID = sod.ProductID
WHERE
DATEPART(YEAR, soh.DueDate) = '2017'
AND DATEPART(MONTH, soh.DueDate) = '05'
OR (DATEPART(MONTH, soh.DueDate) = '06'
OR DATEPART(MONTH, soh.DueDate) = '12')
AND soh.ShipMethod = 'Unknown';
Я неправильно понял этот вопрос, и мне было интересно, может ли кто-нибудь увидеть, что не так с кодом? По-моему, выглядит правильно.
Вопрос:
Каков общий вес в килограммах заказов, подлежащих оплате в мае 2017 года, или июне 2017 года, или декабре 2017 года? Включайте только заказы, в которых использовался неизвестный способ доставки. Получите общий вес, округленный и дополненный до 2dp.
Комментарии:
1. Пожалуйста, предоставьте некоторые примеры данных, ожидаемые результаты и отметьте используемую вами базу данных.
2. И идет перед ИЛИ. Вам нужны скобки. (Или используйте
IN (...)
.)3. где количество в формуле? если я отправлю 100 товаров по 1 кг, что составляет 100 кг плюс проблема с
OR
s в вашем предложении where — он собирает любые строки месяцев 7 или 11, игнорируя год4.
DATEPART
Функции возвращают значения типаINT
— поэтому, чтобы избежать ненужных, дорогостоящих неявных преобразований, при сравнении НЕ заключайте значения сравнения в одинарные кавычки! ИспользованиеDATEPART(YEAR, soh.DueDate) = 2017
одинарных кавычек делает сравнение целочисленным сравнением5. куда исчез вопрос? не уничтожайте вопрос
Ответ №1:
Вам нужно, чтобы вес обоих единиц умножался на количество этих единиц. Если кто-то отправляет один товар или 100 таких товаров, общий вес не будет одинаковым.
Кроме того, вам нужно связать ограничение на год с каждым из ограничений на месяц, чтобы вы получили 2017-04, 2017-07, 2017-11. В вашем оригинале вы получаете 2017-04, но любые строки в месяцах 7 и 11. Используйте круглые скобки для управления значением предикатов.
SELECT
ROUND(SUM(COALESCE(p.[Weight] * sod.OrderQty, 0)), 2) AS [Total weight]
FROM SalesLT.SalesOrderHeader soh
JOIN SalesLT.SalesOrderDetail sod
ON sod.SalesOrderID = soh.SalesOrderID
JOIN SalesLT.Product p
ON p.ProductID = sod.ProductID
WHERE soh.ShipMethod = 'UnKnown'
AND DATEPART(YEAR, soh.DueDate) = 2017
AND (
DATEPART(MONTH, soh.DueDate) = 04
OR DATEPART(MONTH, soh.DueDate) = 07
OR DATEPART(MONTH, soh.DueDate) = 11
)
как упоминалось marc_s, также избегайте преобразования типов, поскольку datepart()
возвращает целые числа.
Лично я бы предпочел использовать 3 полных диапазона дат вместо использования datepart
WHERE soh.ShipMethod = 'UnKnown'
AND (soh.DueDate >= '20170401' and soh.DueDate < '20170501')
AND (soh.DueDate >= '20170701' and soh.DueDate < '20170801')
AND (soh.DueDate >= '20171101' and soh.DueDate < '20171201')