Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将多行转换为多列的SQL语句_Sql_Sql Server_Sql Server 2014 - Fatal编程技术网

将多行转换为多列的SQL语句

将多行转换为多列的SQL语句,sql,sql-server,sql-server-2014,Sql,Sql Server,Sql Server 2014,我有以下资料: DECLARE @tmp TABLE (cid int, pid int, name varchar(10)) Insert Into @tmp (cid, pid, name) Select 31, 18, 'Pot_One' UNION ALL Select 32, 18, 'Pot_One' UNION ALL Select 31, 19, 'Pot_Two' UNION ALL Select 32, 19, 'Pot_Two' UNION ALL Select 33,

我有以下资料:

DECLARE @tmp TABLE (cid int, pid int, name varchar(10))

Insert Into @tmp (cid, pid, name)
Select 31, 18, 'Pot_One' UNION ALL
Select 32, 18, 'Pot_One' UNION ALL
Select 31, 19, 'Pot_Two' UNION ALL
Select 32, 19, 'Pot_Two' UNION ALL
Select 33, 19, 'Pot_Two' UNION ALL
Select 40, 20, 'Pot_Three' 
name         18     19      20
Pot_One      31     NULL    NULL
Pot_Three    NULL   NULL    40
Pot_Two      NULL   31      NULL
这描述了多个cid组合在一起以创建一个pot,例如pot 1中有31个和32个,pot id为18,我们可以在一个pot中有任意数量的cid(最小值为1,最大值为0)

我试图实现的是连续检索pots和相关cid,因此我考虑使用pivot并尝试了以下方法:

SELECT * from 
(
    select cid, pid, name
    from @tmp
) x
pivot 
(
    min(cid)
    for pid in ([18],[19],[20])
) p 
但这将返回以下结果:

DECLARE @tmp TABLE (cid int, pid int, name varchar(10))

Insert Into @tmp (cid, pid, name)
Select 31, 18, 'Pot_One' UNION ALL
Select 32, 18, 'Pot_One' UNION ALL
Select 31, 19, 'Pot_Two' UNION ALL
Select 32, 19, 'Pot_Two' UNION ALL
Select 33, 19, 'Pot_Two' UNION ALL
Select 40, 20, 'Pot_Three' 
name         18     19      20
Pot_One      31     NULL    NULL
Pot_Three    NULL   NULL    40
Pot_Two      NULL   31      NULL
这是错误的,因为pot one中有31和32,这只代表31,我需要的是潜在的:

name         18     18      19    19    19    20
Pot_One      31     32      NULL  NULL  NULL  NULL
Pot_Three    NULL   NULL    NULL  NULL  NULL  40
Pot_Two      NULL   NULL    31    32    33    NULL
我已经更改了pivot以将cid作为列标题,并得到了这一点,这更接近我试图实现的目标:

SELECT * from 
(
    select cid, pid, name
    from @tmp
) x
pivot 
(
    min(pid)
    for cid in ([31],[32],[33],[40])
) p 

name        31    32        33    40
Pot_One     18    18        NULL  NULL
Pot_Three   NULL  NULL      NULL  20
Pot_Two     19    19        19    NULL
我尝试了几种不同的方法,但都没有成功,还有其他方法吗

谢谢

问题在于pivot中的min(cid),它不会提供所有条目。切换到在pid上旋转,给出多个cid结果。子查询该值并将其替换为cid值,其中结果不为NULL

DECLARE @tmp TABLE (cid int, pid int, name varchar(10))

Insert Into @tmp (cid, pid, name)
Select 31, 18, 'Pot_One' UNION ALL
Select 32, 18, 'Pot_One' UNION ALL
Select 31, 19, 'Pot_Two' UNION ALL
Select 32, 19, 'Pot_Two' UNION ALL
Select 33, 19, 'Pot_Two' UNION ALL
Select 40, 20, 'Pot_Three' 

SELECT name, CASE WHEN [18] IS NOT NULL THEN CID END AS [18], CASE WHEN [19] IS NOT NULL THEN CID END AS [19], CASE WHEN [20] IS NOT NULL THEN CID END AS [20]
FROM
(
SELECT * from 
(
    select cid, pid, name
    from @tmp
) x
pivot 
(
    min(pid)
    for pid in ([18],[19],[20])
) p 
) x

这里有一个替代方案

基本上,pot id和pot name是同一事物的两个名称,它们没有变化,因此基本上
18(pot_One)
应该是同一事物的足够好的指示器,然后您可以在该指示器和cid值之间创建两个D映射,以显示它们是否在其中

SELECT * from 
(
    select cid, cast(pid as varchar) +' ('+ name +')' as name, 1 r
    from @tmp
) x
pivot 
(
    min(r)
    for cid in ([31],[32],[33],[40])
) p 
SELECT name, ISNULL([31], 'x') [31],ISNULL([32],'x') [32],ISNULL([33],'x') [33],ISNULL([40],'x') [40] 
from 
(
    select cid, cast(pid as varchar) +' ('+ name +')' as name, '1' r
    from @tmp
) x
pivot 
(
    min(r)
    for cid in ([31],[32],[33],[40])
) p 
输出:

name           31          32          33          40
-------------------------- ----------- ----------- -----------
18 (Pot_One)   1           1           NULL        NULL
19 (Pot_Two)   1           1           1           NULL
20 (Pot_Three) NULL        NULL        NULL        1
此外,您还可以通过如下修改将NULL替换为“X”

SELECT * from 
(
    select cid, cast(pid as varchar) +' ('+ name +')' as name, 1 r
    from @tmp
) x
pivot 
(
    min(r)
    for cid in ([31],[32],[33],[40])
) p 
SELECT name, ISNULL([31], 'x') [31],ISNULL([32],'x') [32],ISNULL([33],'x') [33],ISNULL([40],'x') [40] 
from 
(
    select cid, cast(pid as varchar) +' ('+ name +')' as name, '1' r
    from @tmp
) x
pivot 
(
    min(r)
    for cid in ([31],[32],[33],[40])
) p 
输出

name            31   32   33   40
--------------- ---- ---- ---- ----
18 (Pot_One)    1    1    x    x
19 (Pot_Two)    1    1    1    x
20 (Pot_Three)  x    x    x    1

您希望输出是什么样子的?这看起来有点挑战,但也很有趣。你能提供你想要的输出吗?谢谢你的关注。我需要的是能够以某种方式显示cid 31和32在罐18中,cid 31、32和33在罐19中,cid 40在罐20中。@03Usr请检查我的答案。如果你觉得这个问题有用,请接受和/或投票,以便将来有类似问题的求职者发现这个问题有用。[ ]