如何从单个列中选择多个字段并输出到单个行

时间:2017-10-17 21:25:31

标签: sql-server tsql

sql和new to stack的新手,所以如果这是一个重复的问题,我很抱歉。我很新,我甚至不确定如何表达这个问题,或者是否有可能。

table1
-----------------------------
|  table2.key  |   codes    |
-----------------------------
|  1           |   'pizza'  |
-----------------------------
|  1           |   'cheese' |
-----------------------------
|  2           |   'pizza'  |
-----------------------------
|  3           |   'zebra'  |

table2
-------------------
|  key |  name    |
-------------------
|  1   |  'steve' |
-------------------
|  2   |  'john'  |
-------------------
|  3   |  'ralph  |

不确定如何为我想要的东西组成一个select语句,所以我会从上面的表中向你展示我想要的输出

Desired output
------------------------------------
|  key  |  Name | cPizza  | cCheese|
------------------------------------
|   1   |'steve'| 'pizza'|'cheese' |
------------------------------------
|   2   |'john' | 'pizza'|  ''     |
------------------------------------
|   3   |'ralph'|   ''   |   ''    |

我的情况比这更复杂。我需要为每个id返回一行,但我写的所有内容都为每个代码返回多行。

我想从table2返回所有人,并显示他们是否有披萨或奶酪代码。如果他们不留空。

3 个答案:

答案 0 :(得分:0)

这是一个可以为您提供结果的查询。这不是非常可扩展,但在不知道实际用例的情况下,这将从您的示例中获得所需的结果。

创建测试数据:

DECLARE @table1 TABLE (
    tbl_key INT,
    codes NVARCHAR(MAX)
)

INSERT @table1 VALUES
(1, 'pizza'),
(1, 'cheese'),
(2, 'pizza'),
(3, 'zebra')

DECLARE @table2 TABLE (
    tbl_key INT,
    name NVARCHAR(MAX)
)

INSERT @table2 VALUES
(1, 'steve'),
(2, 'john'),
(3, 'ralph')

查询:

SELECT
    tbl2.tbl_key AS [key],
    tbl2.name AS [Name],
    ISNULL(pizza_tbl.codes, '') AS cPizza,
    ISNULL(cheese_tbl.codes, '') AS cCheese
FROM @table2 tbl2
LEFT JOIN (
    SELECT
        tbl_key,
        codes
    FROM @table1 tbl1
    WHERE codes = 'cheese'
    ) cheese_tbl ON
    tbl2.tbl_key = cheese_tbl.tbl_key
LEFT JOIN (
    SELECT
        tbl_key,
        codes
    FROM @table1 tbl1
    WHERE codes = 'pizza'
    ) pizza_tbl ON
    tbl2.tbl_key = pizza_tbl.tbl_key

答案 1 :(得分:0)

以下是您需要的更短版本

DECLARE @table1 TABLE (
    tbl_key INT,
    codes NVARCHAR(MAX)
)

INSERT @table1 VALUES
(1, 'pizza'),
(1, 'cheese'),
(2, 'pizza'),
(3, 'zebra')

DECLARE @table2 TABLE (
    tbl_key INT,
    name NVARCHAR(MAX)
)

INSERT @table2 VALUES
(1, 'steve'),
(2, 'john'),
(3, 'ralph')


select distinct a.tbl_key as [key] ,a.Name ,isnull(ab.codes,'') as cPizza,isnull(ac.codes,'') as cCheese,isnull(ad.codes,'') as cZebra
from @table2 a 

outer apply (select codes from @table1 where a.tbl_key = tbl_key and codes = 'pizza') as ab 
outer apply (select codes from @table1 where a.tbl_key = tbl_key and codes = 'cheese') as ac 
outer apply (select codes from @table1 where a.tbl_key = tbl_key and codes = 'zebra') as ad 

答案 2 :(得分:0)

如果您事先知道codes的值,则可以使用PIVOT运算符将行转换为列。以下查询:

select tbl_key,name,[pizza] ,[cheese] 
from ( select t2.tbl_key,t2.name,t1.codes
       from table1 t1 inner join table2 t2 on t1.tbl_key=t2.tbl_key
     ) as source
PIVOT 
(
    MAX(codes)
    FOR codes in ([cheese],[pizza])
) as pvt    

将返回

tbl_key name    pizza   cheese
1       steve   pizza   cheese
2       john    pizza   NULL
3       ralph   NULL    NULL

您可以更改列的名称或用空字符串替换NULL:

select tbl_key,name,ISNULL([pizza],'') as cPizza ,ISNULL([cheese],'') as cCheese
from ( select t2.tbl_key,t2.name,t1.codes
       from table1 t1 inner join table2 t2 on t1.tbl_key=t2.tbl_key
     ) as source
PIVOT 
(
    MAX(codes)
    FOR codes in ([cheese],[pizza])
) as pvt    

PIVOT运算符为每组值计算聚合,并使用值名称将其公开为列。在这种情况下,对于cheesepizza值,它会计算MAX(codes),基本上是值本身,并将其公开为cheesepizza列。