行到列 (SQL Server)

Raf*_*ima 1 sql-server t-sql

我有一个有两列的表,一列是发布类型,另一列是值。

来源表:

+-----+-------+
|Type | Value |
+-----+-------+
|  C  | 381.22|
|  D  | 25.49 |
|  C  | 25.49 |
|  D  | 25.48 |
|  C  | 705.56|
|  D  | 80.00 |
+-----+-------+
Run Code Online (Sandbox Code Playgroud)

我需要创建一个分离类型 C 和 D 的视图,并列出它们的值。

我需要它看起来像这样:

+------+-----+
|Credit|Debit|
+------+-----+
|381.22|25.49|
|25.49 |25.48|
|705.56|80.00|
+------+-----+
Run Code Online (Sandbox Code Playgroud)

我尝试使用 SELECTS 创建两个单独的虚拟列,只是为了列出相应类型的值。

SELECT 
    (SELECT [value] FROM [table] WHERE [type] IN ('D')) AS Debit,
    (SELECT [value] FROM [table] WHERE [type] IN ('C')) AS Credit
Run Code Online (Sandbox Code Playgroud)

发生错误是因为两个 SELECTS 都返回多个结果:

Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
Run Code Online (Sandbox Code Playgroud)

也尝试使用 PIVOT语句,但还是不成功。

你能给我一个解决这个问题的建议吗?

Tar*_*ryn 5

有几种方法可以获得您想要的最终结果。您可以使用PIVOT或也可以将聚合函数与CASE表达式一起使用,但是为了为每个返回多行,Type您需要创建一个唯一的值,您可以GROUP BY

我建议使用窗口函数,例如row_number首先为表中由TYPE. 你会写这个类似于:

select 
  [Type],
  [Value],
  rn = row_number() over(partition by [Type] order by (select 1))
from yourtable;
Run Code Online (Sandbox Code Playgroud)

这会通过Typeaka Credit orDebit`为表中的每一行创建一个唯一值。当您聚合数据时需要这样做,因此您将返回多行。

创建此行号后,您可以使用PIVOT函数或CASE聚合将数据转换为列。

select 
  Credit = max(case when [Type] = 'C' then [Value] end),
  Debit = max(case when [Type] = 'D' then [Value] end)
from
(
  select 
    [Type],
    [Value],
    rn = row_number() over(partition by [Type] order by (select 1))
  from yourtable
) d
group by rn;
Run Code Online (Sandbox Code Playgroud)

或者:

select 
  Credit = C,
  Debit = D
from
(
  select 
    [Type],
    [Value],
    rn = row_number() over(partition by [Type] order by (select 1))
  from yourtable
) d
pivot
(
  max(value)
  for [Type] in (C, D)
) p;
Run Code Online (Sandbox Code Playgroud)

这是一个演示。这两个都返回结果:

| Credit | Debit |
|--------|-------|
| 381.22 |    80 |
|  25.49 | 25.48 |
| 705.56 | 25.49 |
Run Code Online (Sandbox Code Playgroud)

如果您需要CreditDebit数据专门出现在某些行中,那么您需要提供一些额外的数据来将每个数据Credit或数据联系Debit在一起。这些版本只是将行转换为数据列。