想知道是否有人可以帮我查询我试图用来从我的数据库中提取销售信息的查询。我正在尝试建立一份报告,以显示各州的所有销售情况。我遇到过这段代码,虽然它接近我需要的东西,但并不是全部。
随着每个州的销售,我需要包括库存销售的仓库(T1。[WhsCode])。我还需要对每一列进行求和(我知道您可以按Ctrl和Click来获取每列底部的总计,但希望它们自动出现在最终报告中)。有人可以帮忙吗?
以下是目前的查询:
SELECT T0.State1 AS 'Bill-to State',
(
SELECT SUM(T1.DocTotal)
FROM OINV T1 WITH ( NOLOCK )
INNER JOIN OCRD T2 ON T2.CardCode = T1.CardCode
WHERE MONTH(T1.DOCDATE) = 1 AND
T2.State1 = T0.State1 AND
YEAR(T1.DOCDATE) = YEAR(GETDATE())
) AS 'JAN Amt',
(
SELECT SUM(T1.DocTotal)
FROM OINV T1 WITH ( NOLOCK )
INNER JOIN OCRD T2 ON T2.CardCode = T1.CardCode
WHERE MONTH(T1.DOCDATE) = 2 AND
T2.State1 = T0.State1 AND
YEAR(T1.DOCDATE) = YEAR(GETDATE())
) AS 'FEB Amt',
(
SELECT SUM(T1.DocTotal)
FROM OINV T1 WITH ( NOLOCK )
INNER JOIN OCRD T2 ON T2.CardCode = T1.CardCode
WHERE MONTH(T1.DOCDATE) = 3 AND
T2.State1 = T0.State1 AND
YEAR(T1.DOCDATE) = YEAR(GETDATE())
) AS 'MAR Amt',
(
SELECT SUM(T1.DocTotal)
FROM OINV T1 WITH ( NOLOCK )
INNER JOIN OCRD T2 ON T2.CardCode = T1.CardCode
WHERE MONTH(T1.DOCDATE) = 4 AND
T2.State1 = T0.State1 AND
YEAR(T1.DOCDATE) = YEAR(GETDATE())
) AS 'APR Amt',
(
SELECT SUM(T1.DocTotal)
FROM OINV T1 WITH ( NOLOCK )
INNER JOIN OCRD T2 ON T2.CardCode = T1.CardCode
WHERE MONTH(T1.DOCDATE) = 5 AND
T2.State1 = T0.State1 AND
YEAR(T1.DOCDATE) = YEAR(GETDATE())
) AS 'MAY Amt',
(
SELECT SUM(T1.DocTotal)
FROM OINV T1 WITH ( NOLOCK )
INNER JOIN OCRD T2 ON T2.CardCode = T1.CardCode
WHERE MONTH(T1.DOCDATE) = 6 AND
T2.State1 = T0.State1 AND
YEAR(T1.DOCDATE) = YEAR(GETDATE())
) AS 'JUN Amt',
(
SELECT SUM(T1.DocTotal)
FROM OINV T1 WITH ( NOLOCK )
INNER JOIN OCRD T2 ON T2.CardCode = T1.CardCode
WHERE MONTH(T1.DOCDATE) = 7 AND
T2.State1 = T0.State1 AND
YEAR(T1.DOCDATE) = YEAR(GETDATE())
) AS 'JUL Amt',
(
SELECT SUM(T1.DocTotal)
FROM OINV T1 WITH ( NOLOCK )
INNER JOIN OCRD T2 ON T2.CardCode = T1.CardCode
WHERE MONTH(T1.DOCDATE) = 8 AND
T2.State1 = T0.State1 AND
YEAR(T1.DOCDATE) = YEAR(GETDATE())
) AS 'AUG Amt',
(
SELECT SUM(T1.DocTotal)
FROM OINV T1 WITH ( NOLOCK )
INNER JOIN OCRD T2 ON T2.CardCode = T1.CardCode
WHERE MONTH(T1.DOCDATE) = 9 AND
T2.State1 = T0.State1 AND
YEAR(T1.DOCDATE) = YEAR(GETDATE())
) AS 'SEP Amt',
(
SELECT SUM(T1.DocTotal)
FROM OINV T1 WITH ( NOLOCK )
INNER JOIN OCRD T2 ON T2.CardCode = T1.CardCode
WHERE MONTH(T1.DOCDATE) = 10 AND
T2.State1 = T0.State1 AND
YEAR(T1.DOCDATE) = YEAR(GETDATE())
) AS 'OCT Amt',
(
SELECT SUM(T1.DocTotal)
FROM OINV T1 WITH ( NOLOCK )
INNER JOIN OCRD T2 ON T2.CardCode = T1.CardCode
WHERE MONTH(T1.DOCDATE) = 11 AND
T2.State1 = T0.State1 AND
YEAR(T1.DOCDATE) = YEAR(GETDATE())
) AS 'NOV Amt',
(
SELECT SUM(T1.DocTotal)
FROM OINV T1 WITH ( NOLOCK )
INNER JOIN OCRD T2 ON T2.CardCode = T1.CardCode
WHERE MONTH(T1.DOCDATE) = 12 AND
T2.State1 = T0.State1 AND
YEAR(T1.DOCDATE) = YEAR(GETDATE())
) AS 'DEC Amt'
FROM dbo.OCRD T0
LEFT JOIN dbo.OINV T1 ON T1.CardCode = T0.CardCode
GROUP BY T0.State1
ORDER BY T0.State1
答案 0 :(得分:0)
而是使用SQL Pivot:
-- Pivot table with one row and five columns
SELECT 'AverageCost' AS Cost_Sorted_By_Production_Days,
[0], [1], [2], [3], [4]
FROM
(SELECT DaysToManufacture, StandardCost
FROM Production.Product) AS SourceTable
PIVOT
(
AVG(StandardCost)
FOR DaysToManufacture IN ([0], [1], [2], [3], [4])
) AS PivotTable;
答案 1 :(得分:0)
您可以使用条件聚合:
SELECT [Bill-To-State] = ISNULL(T0.State1, 'Total'),
Warehouse = T1.[WhsCode],
[Jan Amt] = SUM(CASE WHEN DATEPART(MONTH, T1.DocDate) = 1 THEN T1.DocTotal ELSE 0 END),
[Feb Amt] = SUM(CASE WHEN DATEPART(MONTH, T1.DocDate) = 2 THEN T1.DocTotal ELSE 0 END),
[Mar Amt] = SUM(CASE WHEN DATEPART(MONTH, T1.DocDate) = 3 THEN T1.DocTotal ELSE 0 END),
[Apr Amt] = SUM(CASE WHEN DATEPART(MONTH, T1.DocDate) = 4 THEN T1.DocTotal ELSE 0 END),
[May Amt] = SUM(CASE WHEN DATEPART(MONTH, T1.DocDate) = 5 THEN T1.DocTotal ELSE 0 END),
[Jun Amt] = SUM(CASE WHEN DATEPART(MONTH, T1.DocDate) = 6 THEN T1.DocTotal ELSE 0 END),
[Jul Amt] = SUM(CASE WHEN DATEPART(MONTH, T1.DocDate) = 7 THEN T1.DocTotal ELSE 0 END),
[Aug Amt] = SUM(CASE WHEN DATEPART(MONTH, T1.DocDate) = 8 THEN T1.DocTotal ELSE 0 END),
[Sep Amt] = SUM(CASE WHEN DATEPART(MONTH, T1.DocDate) = 9 THEN T1.DocTotal ELSE 0 END),
[Oct Amt] = SUM(CASE WHEN DATEPART(MONTH, T1.DocDate) = 10 THEN T1.DocTotal ELSE 0 END),
[Nov Amt] = SUM(CASE WHEN DATEPART(MONTH, T1.DocDate) = 11 THEN T1.DocTotal ELSE 0 END),
[Dec Amt] = SUM(CASE WHEN DATEPART(MONTH, T1.DocDate) = 12 THEN T1.DocTotal ELSE 0 END)
FROM dbo.OCRD T0
LEFT JOIN dbo.OINV T1
ON T1.CardCode = T0.CardCode
WHERE T1.DocDate >= DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()), 0)
AND T1.DocDate < DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()) + 1, 0)
GROUP BY GROUPING SETS ((T0.State1, T1.[WhsCode]), ());
N.B我已使用我首选的Alias = Expression
方法移除了deprecated literals for aliases。我更喜欢这个,因为我发现能够更容易地看到立即调用列,而不是必须向右扫描才能找到列的结尾。这完全是个人偏好,如果您对expression AS Alias
更熟悉,那么您应该使用以下内容,因为它仍然避免使用文字。
SELECT ISNULL(T0.State1, 'Total') AS [Bill-To-State],
T1.[WhsCode] AS Warehouse,
SUM(CASE WHEN DATEPART(MONTH, T1.DocDate) = 1 THEN T1.DocTotal ELSE 0 END) AS [Jan Amt],
SUM(CASE WHEN DATEPART(MONTH, T1.DocDate) = 2 THEN T1.DocTotal ELSE 0 END) AS [Feb Amt],
SUM(CASE WHEN DATEPART(MONTH, T1.DocDate) = 3 THEN T1.DocTotal ELSE 0 END) AS [Mar Amt],
SUM(CASE WHEN DATEPART(MONTH, T1.DocDate) = 4 THEN T1.DocTotal ELSE 0 END) AS [Apr Amt],
SUM(CASE WHEN DATEPART(MONTH, T1.DocDate) = 5 THEN T1.DocTotal ELSE 0 END) AS [May Amt],
SUM(CASE WHEN DATEPART(MONTH, T1.DocDate) = 6 THEN T1.DocTotal ELSE 0 END) AS [Jun Amt],
SUM(CASE WHEN DATEPART(MONTH, T1.DocDate) = 7 THEN T1.DocTotal ELSE 0 END) AS [Jul Amt],
SUM(CASE WHEN DATEPART(MONTH, T1.DocDate) = 8 THEN T1.DocTotal ELSE 0 END) AS [Aug Amt],
SUM(CASE WHEN DATEPART(MONTH, T1.DocDate) = 9 THEN T1.DocTotal ELSE 0 END) AS [Sep Amt],
SUM(CASE WHEN DATEPART(MONTH, T1.DocDate) = 10 THEN T1.DocTotal ELSE 0 END) AS [Oct Amt],
SUM(CASE WHEN DATEPART(MONTH, T1.DocDate) = 11 THEN T1.DocTotal ELSE 0 END) AS [Nov Amt],
SUM(CASE WHEN DATEPART(MONTH, T1.DocDate) = 12 THEN T1.DocTotal ELSE 0 END) AS [Dec Amt]
FROM dbo.OCRD T0
LEFT JOIN dbo.OINV T1
ON T1.CardCode = T0.CardCode
WHERE T1.DocDate >= DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()), 0)
AND T1.DocDate < DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()) + 1, 0)
GROUP BY GROUPING SETS ((T0.State1, T1.[WhsCode]), ());
另请注意,我已更换
WHERE YEAR(T1.DocDate) = YEAR(GETDATE())
用
WHERE T1.DocDate >= DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()), 0)
AND T1.DocDate < DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()) + 1, 0)
这可能看起来很长,但它会允许优化器使用t1.DocDate上的任何索引,因为不必在每一行都执行YEAR
函数。
另一件事是
的使用GROUP BY GROUPING SETS ((T0.State1, T1.[WhsCode]), ());
这将添加您的总行数,您必须有两个结果集,一个按“(T0.State1, T1.[WhsCode])
”分组,一个分组为“()
”。在此总行中,T0.State1
和T1.[WhsCode]
都将为空,因此我使用ISNULL(T0.State1, 'Total')
使其在此行中显示总计。