我有这张桌子:
+---------+------+---------+
| 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
的方法吗?
答案 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.?;