gpt4 book ai didi

sql-server - 将 ROWS 获取为 COLUMNS(SQL Server 动态 PIVOT 查询)

转载 作者:行者123 更新时间:2023-12-02 09:02:10 25 4
gpt4 key购买 nike

我正在使用 MS SQL 2008 R2,有三个具有以下架构的表:

表 1:包含每个 worker 的轮类信息

CREATE TABLE workshift (
[ws_id] [bigint] NOT NULL,
[start_date] [datetime] NOT NULL,
[end_date] [datetime] NOT NULL,
[worker_id] [bigint] NOT NULL
)

INSERT INTO workshift VALUES (1, '2012-08-20 08:30:00', '2012-08-20 14:30:00', 1)
INSERT INTO workshift VALUES (2, '2012-08-20 14:30:00', '2012-08-20 22:30:00', 2)

表 2:包含货币面额

CREATE TABLE currency_denom (
[cd_id] [decimal](7, 2) NOT NULL,
[name] [nchar](100) NOT NULL
)

INSERT INTO currency_denom VALUES (1, '100.00')
INSERT INTO currency_denom VALUES (2, '50.00')
INSERT INTO currency_denom VALUES (3, '20.00')
INSERT INTO currency_denom VALUES (4, '10.00')
INSERT INTO currency_denom VALUES (5, '5.00')
INSERT INTO currency_denom VALUES (6, '1.00')

表 3:包含 worker 在每个轮类中收到的每种面额的数量

CREATE TABLE currency_by_workshift (
[cd_id] [decimal](7, 2) NOT NULL,
[ws_id] [bigint] NOT NULL,
[qty] [int] NOT NULL
)

INSERT INTO currency_by_workshift VALUES (1, 1, 1)
INSERT INTO currency_by_workshift VALUES (2, 1, 2)
INSERT INTO currency_by_workshift VALUES (3, 1, 2)
INSERT INTO currency_by_workshift VALUES (2, 2, 3)
INSERT INTO currency_by_workshift VALUES (4, 2, 4)
INSERT INTO currency_by_workshift VALUES (5, 2, 2)

我需要获取列而不是行中的currency_by_workshift值以及工作类次值,即:

workshift |     workshift       |     workshift       | 100.00 | 50.00 | 20.00 | 10.00 | 5.00 | 1.00 
ws_id | start_date | end_date | | | | | |

1 | 2012-08-20 08:30:00 | 2012-08-20 14:30:00 | 1 | 2 | 2 | 0 | 0 | 0
2 | 2012-08-20 14:30:00 | 2012-08-20 22:30:00 | 0 | 2 | 0 | 4 | 2 | 0

我无法使用案例来计算每种货币面额的数量,因为它们是可配置的,如果添加新面额,则应修改查询。如果使用 PIVOT 函数也同样适用,还是我错了?

我怎样才能通过这种方式获取信息?

最佳答案

您正在尝试做的事情称为 PIVOT 。有两种方法可以做到这一点,即使用静态枢轴或动态枢轴。

静态透视 - 您可以在其中对行值进行硬编码以转换为列(请参阅 SQL Fiddle with Demo ):

select ws_id,
start_date,
end_date,
IsNull([100.00], 0) [100.00],
IsNull([50.00], 0) [50.00],
IsNull([20.00], 0) [20.00],
IsNull([10.00], 0) [10.00],
IsNull([5.00], 0) [5.00],
IsNull([1.00], 0) [1.00]
from
(
select ws.ws_id,
ws.start_date,
ws.end_date,
cd.name,
cbw.qty
from workshift ws
left join currency_by_workshift cbw
on ws.ws_id = cbw.ws_id
left join currency_denom cd
on cbw.cd_id = cd.cd_id
) x
pivot
(
sum(qty)
for name in ([100.00], [50.00], [20.00], [10.00], [5.00], [1.00])
) p

动态枢轴是在运行时确定列的位置(请参阅 SQL Fiddle with Demo ):

DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX),
@colsPivot AS NVARCHAR(MAX)

select @colsPivot =
STUFF((SELECT ', IsNull(' + QUOTENAME(rtrim(name)) +', 0) as ['+ rtrim(name)+']'
from currency_denom
GROUP BY name
ORDER BY cast(name as decimal(10, 2)) desc
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')

select @cols = STUFF((SELECT distinct ', ' + QUOTENAME(name)
from currency_denom
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')


set @query
= 'SELECT ws_id, start_date, end_date,' + @colsPivot + ' from
(
select ws.ws_id,
ws.start_date,
ws.end_date,
cd.name,
cbw.qty
from workshift ws
left join currency_by_workshift cbw
on ws.ws_id = cbw.ws_id
left join currency_denom cd
on cbw.cd_id = cd.cd_id
) x
pivot
(
sum(qty)
for name in (' + @cols + ')
) p '

execute(@query)

两个版本都会产生相同的结果。

关于sql-server - 将 ROWS 获取为 COLUMNS(SQL Server 动态 PIVOT 查询),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12074939/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com