我正在寻找一个性能良好的T-SQL查询,以提供大量行数N列。但每行的列数不一样。
例如 - 我有一个像下面这样约有100万行的订单。
Order OrderID Date ======== ======== 1 20160102 2 20160402
每个订单可以有N个订单。
我的订单行表约有150万行;
OrderLine OrderID OrderLine ProductID Amount ======== ======== ========== ========== 1 1 3245 299.00 2 1 9876 799.00 2 2 5466 899.00 2 3 7752 599.00
我想要一个像以下一样的结果:
OrderID Date ProductID1 Amount1 ProductID2 Amount2 ProductID3 Amount3 ======== ======== ========== ======= ========== ======= ========== ======= 1 20160102 3245 299.00 2 20160402 9876 799.00 5466 899.00 7752 599.00
每个订单的订单数量可能很大(如50)。
我想我可以使用子选择,但这需要N个子选择 - 而且表现非常糟糕
SELECT OrderID, Date, (SELECT ProductID FROM ORDERLINE OI JOIN O ON O.OrderID=OI.OrderID WHERE ORDERLINE=1) AS ProductID1, (SELECT Amount FROM ORDERLINE OI JOIN O ON O.OrderID=OI.OrderID WHERE ORDERLINE=1) AS Amount1, ... (SELECT ProductID FROM ORDERLINE OI JOIN O ON O.OrderID=OI.OrderID WHERE ORDERLINE=N) AS ProductIDN, (SELECT Amount FROM ORDERLINE OI JOIN O ON O.OrderID=OI.OrderID WHERE ORDERLINE=N) AS AmountN FROM ORDER O
另一个选择可能是转动。 但正如我所看到的那样 - 它不是“传统的”转动 - 它将是动态的转动。
但是我不确定那会是什么样子和表演?
答案 0 :(得分:1)
我建议使用条件聚合:
SELECT o.OrderID, o.Date,
MAX(CASE WHEN ol.orderline = 1 THEN ProductId END) as ProductId1,
MAX(CASE WHEN ol.orderline = 1 THEN Amount END) as Amount1,
MAX(CASE WHEN ol.orderline = 2 THEN ProductId END) as ProductId2,
MAX(CASE WHEN ol.orderline = 2 THEN Amount END) as Amount2,
. . .
FROM ORDER O JOIN
ORDERLINE OI
ON O.OrderID = OI.OrderID
GROUP BY o.OrderID, o.Date;
除非你有一个名为o
的表,否则我不希望你的版本有效。正确的语法是:
(SELECT ProductID FROM ORDERLINE OI WHERE O.OrderID = OI.OrderID AND ORDERLINE = 1) AS ProductID1,
答案 1 :(得分:1)
如果你需要动态
Declare @SQL varchar(max) = Stuff((Select Distinct ',' + QuoteName(concat('ProductID',OrderLine))+','+ QuoteName(concat('Amount',OrderLine)) From OrderLine Order by 1 For XML Path('')),1,1,'')
Select @SQL = '
Select [OrderID],[Date],' + @SQL + '
From (
Select A.OrderID
,A.Date
,C.*
From [Order] A
Join OrderLine B on (A.OrderID=B.OrderID)
Cross Apply (Values (concat(''ProductID'',B.OrderLine),cast(B.ProductID as varchar(25)))
,(concat(''Amount'' ,B.OrderLine),cast(B.Amount as varchar(25)))
) C (Item,Value)
) A
Pivot (max(Value) For [Item] in (' + @SQL + ') ) p'
Exec(@SQL);
返回