我有查询的源表
SELECT
DATENAME(MONTH, sales_timestamp) as Month_Name, COUNT(nc_deposit) as piece,
ISNULL(sum(nc_deposit),0) as amount,terminal_name
FROM dbfastshosted.dbo.fh_mf_new_card_logs cl
INNER JOIN dbfastshosted.dbo.fh_sales_map m
on cl.nc_log_id = m.nc_log_id
INNER JOIN dbfastshosted.dbo.fh_sales_logs sl
on m.sales_id = sl.sales_id
INNER JOIN dbfastsconfigdataref.dbo.cdf_terminal_user_account h
on cl.created_user_id = h.terminal_user_id
INNER JOIN dbfastsconfigdataref.dbo.cdf_terminal t
on h.terminal_id = t.terminal_id
INNER JOIN dbfastsconfigdataref.dbo.cdf_cuid c
on cl.cu_id = c.cu_id
WHERE YEAR(sales_timestamp)='2017'
and cl.currency_id = 2
and c.card_type_id = '514'
GROUP BY terminal_name, DATENAME(MONTH,sales_timestamp), DATEPART(m,sales_timestamp)
ORDER BY DATEPART(m, sales_timestamp), terminal_nameerminal_name
我希望以数据透视的形式提供数据。所以我将查询修改为:
WITH source_table (
terminal_name
,Month_Name
,piece
,amount
)
AS (
SELECT DATENAME(MONTH, sales_timestamp) AS Month_Name
,COUNT(nc_deposit) AS piece
,ISNULL(sum(nc_deposit), 0) AS amount
,terminal_name
FROM dbfastshosted.dbo.fh_mf_new_card_logs cl
INNER JOIN dbfastshosted.dbo.fh_sales_map m ON cl.nc_log_id = m.nc_log_id
INNER JOIN dbfastshosted.dbo.fh_sales_logs sl ON m.sales_id = sl.sales_id
INNER JOIN dbfastsconfigdataref.dbo.cdf_terminal_user_account h ON cl.created_user_id = h.terminal_user_id
INNER JOIN dbfastsconfigdataref.dbo.cdf_terminal t ON h.terminal_id = t.terminal_id
INNER JOIN dbfastsconfigdataref.dbo.cdf_cuid c ON cl.cu_id = c.cu_id
WHERE YEAR(sales_timestamp) = '2017'
AND cl.currency_id = 2
AND c.card_type_id = '514'
GROUP BY DATENAME(MONTH, sales_timestamp)
,terminal_name
,DATEPART(m, sales_timestamp)
ORDER BY DATEPART(m, sales_timestamp)
,terminal_name
)
SELECT pieces.terminal_name
,pieces.January AS JanPcs
,amounts.January AS JanAmt
,pieces.February AS FebPcs
,amounts.February AS FebAmt
,pieces.March AS MarPcs
,amounts.March AS MarAmt
,pieces.April AS AprilPcs
,amounts.April AS AprilAmt
,pieces.May AS MayPcs
,amounts.May AS MayAmt
,pieces.June AS JunePcs
,amounts.June AS JuneAmt
,pieces.July AS JulyPcs
,amounts.July AS JulyAmt
,pieces.August AS AugustPcs
,amounts.August AS AugustAmt
,pieces.September AS SeptPcs
,amounts.September AS SeptAmt
,pieces.October AS OctPcs
,amounts.October AS OctAmt
,pieces.November AS NovPcs
,amounts.November AS NovAmt
,pieces.December AS DecPcs
,amounts.December AS DecAmt
FROM (
SELECT *
FROM (
SELECT terminal_name
,Month_Name
,piece
FROM source_table
) AS src_pieces
PIVOT(MAX(piece) FOR Month_Name IN (
January
,February
,March
,April
,May
,June
,July
,August
,September
,October
,November
,December
)) AS pvt_pieces
) AS pieces
INNER JOIN (
SELECT *
FROM (
SELECT terminal_name
,Month_Name
,amount
FROM source_table
) AS src_pieces
PIVOT(MAX(amount) FOR Month_Name IN (
January
,February
,March
,April
,May
,June
,July
,August
,September
,October
,November
,December
)) AS pvt_pieces
) AS amounts ON (amounts.terminal_name = pieces.terminal_name)
输出应该是这样的:
terminal_name JanAmt JanPcs .... DecAmt DecPcs
------------------------------------------------------------
terminal A 1000 100 2000 200
但是,我收到了这个错误
ORDER BY子句在视图,内联函数中派生无效 表,子查询和公用表表达式,除非TOP,OFFSET 或者也指定了FOR XML。
我多次尝试解决这个问题,但我没有任何想法。你们可以看看这个吗?谢谢!
答案 0 :(得分:0)
CTE不能有ORDER BY。
您可以使用:
WITH CTE AS:
您的查询
SELECT * FROM CTE ORDER BY ...
答案 1 :(得分:0)
条件聚合不会更简单吗?
SELECT terminal_name
sum(case when month(sales_timestamp) = 1 then nc_deposit else 0 end) as jan_amount,
sum(case when month(sales_timestamp) = 2 then nc_deposit else 0 end) as feb_amount,
. . .
sum(case when month(sales_timestamp) = 12 then nc_deposit else 0 end) as dec_amount
FROM dbfastshosted.dbo.fh_mf_new_card_logs cl INNER JOIN
dbfastshosted.dbo.fh_sales_map m
on cl.nc_log_id = m.nc_log_id INNER JOIN
dbfastshosted.dbo.fh_sales_logs sl
on m.sales_id = sl.sales_id INNER JOIN
dbfastsconfigdataref.dbo.cdf_terminal_user_account h
on cl.created_user_id = h.terminal_user_id INNER JOIN
dbfastsconfigdataref.dbo.cdf_terminal t
on h.terminal_id = t.terminal_id INNER JOIN
dbfastsconfigdataref.dbo.cdf_cuid c
on cl.cu_id = c.cu_id
WHERE YEAR(sales_timestamp) = 2017 AND
cl.currency_id = 2 AND
c.card_type_id = 514
GROUP BY terminal_name
ORDER BY terminal_name ;
这似乎比使用CTE,多个子查询和其他JOIN
的多部分查询简单得多。
请注意,我从'2017'
删除了单引号。 YEAR()
函数返回一个数字,因此比较应该是一个数字。同样,我假设card_type_id
是一个数字,而不是一个字符串。