SQL Pivot将2列转换为行

时间:2019-08-22 11:31:29

标签: sql sql-server pivot

我在MsSql 2017中有一个StockLines表。它具有列:

 Product, QuantityInStock, ReservedQuantity.
 CocaCola        50                20

现在我需要在两行中显示该信息:

Product      Quantity         Reserved
CocaCola        20              true
CocaCola        30              false

是否可以使用Pivot()实现?我在正确的道路上吗? PS我正在使用Entity Framework Core。

3 个答案:

答案 0 :(得分:2)

您可以使用apply轻松完成此操作:

select t.product, v.quantity, v.reserved
from t cross apply
     (values (t.ReservedQuantity, 'true'),
             (t.QuantityInStock - t.ReservedQuantity, 'false')
     ) v(quantity, reserved);

我认为您可以使用unpivot来做到这一点,但这是多余的语法。 apply实现了非常强大的横向联接。这只是如何使用它们的一个例子。

答案 1 :(得分:1)

一个简单易懂的方法是UNION:

SELECT product, reservedquantity as quantity, 'true' as reserved FROM stocklines
UNION ALL
SELECT product, quantityinstock-reservedquantity, 'false' FROM stocklines

我想知道表格中是否还有其他行,详细说明了同一产品的其他保留,它们是否也应该来自总数?所有行的库存量是否相同?希望将所有单独的产品预订归为一组,以便库存行表格中每个产品包含一行(否则情况会变得混乱)

您还提到您正在使用ef core-请参见https://docs.microsoft.com/en-us/ef/core/querying/raw-sql

也可以将该技术修改为LINQ语句,可能类似于(未经测试):

context.StockLines.Select(s => new[] { new {
    s.Product,
    Quantity = s.QuantityInStock - s.ReservedQuantity,
    Reserved = false
  },
  new {
    s.Product,
    Quantity = s.ReservedQuantity,
    Reserved = true
  }
}).SelectMany().ToList()

这样的想法是,我们将每条记录分成一个匿名类型,该类型代表保留的类型,另一个类型代表未保留的类型,作为第一个选择的数组输出,然后使用selectmany将类型可枚举的数组展平为令人困惑的类型

后一种解决方案可能需要调整。完全未经测试

答案 2 :(得分:0)

您可以使用UNPIVOT

SELECT Product,
        Quantity,
        CASE Reserved
             WHEN 'QuantityInStock' THEN 'FALSE'
             ELSE 'TRUE'
        END  AS Reserved
 FROM   pro
        UNPIVOT(
            Quantity FOR Reserved IN (QuantityInStock, ReservedQuantity)
        )    AS t

另一种方法是不使用CASE运算符,但使用子查询和别名:

 SELECT Product,
        Quantity,
        Reserved
 FROM   (
            SELECT product,
                   QuantityInStock   AS [false],
                   ReservedQuantity  AS [true]
            FROM   pro
        ) AS tt
        UNPIVOT(Quantity FOR Reserved IN ([false], [true])) upvt