将行分成多行

时间:2019-08-10 03:51:57

标签: sql sql-server

我有这张桌子:

+---------+------+---------+
|  Col1   | Col2 |  Col3   |
+---------+------+---------+
| PersonA | $10  | PersonB |
| PersonC | $20  | PersonD |
+---------+------+---------+

我想要这样的结果:

+---------+-----+-----+
|  Col1   | Db  | Cr  |
+---------+-----+-----+
| PersonA | 0   | $10 |
| PersonB | $10 | 0   |
| PersonC | 0   | $20 |
| PersonD | $20 | 0   |
+---------+-----+-----+

有没有不用Union all的方法吗?

3 个答案:

答案 0 :(得分:4)

如果col1代表CR,col3代表DB,则可以使用UNION ALL来获得所需的输出-

SELECT col1 PersonName, 
'$0' DB,
col2 CR    
FROM your_table

UNION ALL

SELECT col3 PersonName,
col2 DB, 
'$0' CR    
FROM your_table

要使交易订单保持原始状态,您需要先创建ROW_NUMBER,然后再通过RN进行订购。在不同的数据库中,ROW_NUMBER的创建是不同的。您没有提到数据库名称,因此无法在此处添加该逻辑。

当您寻求避免使用UNION ALL时,如果您使用的是MSSQL,则可以考虑以下UNPIVOT-

WITH CTE AS
(
    SELECT U.PersonName,
    CASE WHEN U.name = 'Col3' THEN U.Col2 ELSE '$0' END AS Db,
    CASE WHEN U.name = 'Col1' THEN U.Col2 ELSE '$0' END AS Cr,
    U.name ValuesFromColumn -- Just print this for better understanding
    FROM your_table S
    UNPIVOT
    (
        PersonName
        FOR NAME IN (col1,col3)
    ) U
)

-- Now select from CTE and Join other table as

SELECT * 
FROM CTE A
LEFT JOIN Other_Table B ON....

-- OR Like

SELECT * 
FROM Other_Table A
LEFT JOIN CTE B ON....

UNPIVOT在其他数据库中也可用。如果您正在使用其他数据库,则可以相应地调整语法。

答案 1 :(得分:2)

您可以通过在MSSQL中使用unpivot来实现此目的,因为您希望将列转换为行。请访问此链接,以获取有关在SQL中取消透视的更多信息。UNPIVOT

带有UNPIVOT的{​​{1}}足以获得结果。

case

答案 2 :(得分:0)

使用apply

select v.*
from t cross apply
     (values (t.col1, t.col2, 0),
             (t.col3, 0, t.col2)
     ) v(col1, db, cr);

横向联接(apply的实现)非常强大。在这种情况下,它应该是解决此问题的最简洁,最有效的方法。

Here是db <>小提琴。

编辑:

您可以继续添加联接或apply

select v.*
from t cross apply
     (values (t.col1, t.col2, 0),
             (t.col3, 0, t.col2)
     ) v(col1, db, cr) left join
     x
     on x.? = v.?;