我有2个表,产品和定价。表产品是父表,而定价是子表。当我使用Product中的外键查询表B时,我想为每个外键生成恰好11行,有或没有数据(null填充所有空行和列)
以下是我到目前为止的样本。不能正常工作,但基本上我的目标是,为每个ProductID生成11行,用空值填充空行列
SELECT TOP 11
row_number() over(order by TheCount desc) AS row_num, PRODID, packageID
FROM
(
select count(*) AS TheCount , PRODID ,max(PricingID) AS packageID
from
Product left outer join Pricing on PRODID = ProductID
group by PRODID
UNION ALL
SELECT TOP 11 -1, NULL, NULL, NULL, NULL, NUK
FROM sys.columns
) T
例如
row_num PRODID PRICINGID COSBeginQty COSColCode COSTrade COSTypeOfPrice COSIsActive
1 A10D8642-F6DA-499E-9FC9-024FED104877 F82F533E-C1A0-4DC5-BB2C-06FFF2E59C18 2 NULL T2 A 1
2 A10D8642-F6DA-499E-9FC9-024FED104877 372E6B36-F9D1-4EFA-8A15-08CE673EFFBA 12 NULL T1 A 1
3 A10D8642-F6DA-499E-9FC9-024FED104877 45E77A6F-DC2A-44BF-B6AE-0BE27BD2205F 7 NULL T2 A 1
4 A10D8642-F6DA-499E-9FC9-024FED104877 NULL NULL NULL NULL NULL NULL
5 A10D8642-F6DA-499E-9FC9-024FED104877 NULL NULL NULL NULL NULL NULL
6 A10D8642-F6DA-499E-9FC9-024FED104877 NULL NULL NULL NULL NULL NULL
7 A10D8642-F6DA-499E-9FC9-024FED104877 NULL NULL NULL NULL NULL NULL
8 A10D8642-F6DA-499E-9FC9-024FED104877 NULL NULL NULL NULL NULL NULL
9 A10D8642-F6DA-499E-9FC9-024FED104877 NULL NULL NULL NULL NULL NULL
10 A10D8642-F6DA-499E-9FC9-024FED104877 NULL NULL NULL NULL NULL NULL
11 A10D8642-F6DA-499E-9FC9-024FED104877 NULL NULL NULL NULL NULL NULL
这是一个SQLFiddle链接,显示我正在努力扩展的数据和工作查询,以便它扩展到第11个,即显示11行作为列。
使用Damiens示例代码,我已经能够将下面的代码放在一起。它可以将产品表中的元素交叉应用到Pricing表中,但是,我更喜欢这样一种情况:它不会将相同的PricingID应用于产品表中的所有ProductID,而只应用于定价记录适用的特定ProductId。 。
答案 0 :(得分:0)
基本方法是使用数字表ROW_NUMBER()
和左连接:
select
*
from
sys.tables st
cross join
(select distinct number from master..spt_values where number between 1 and 11) n
left join
(select *,ROW_NUMBER() OVER (PARTITION BY object_id order by name) rn from sys.columns) sc
on
st.object_id = sc.object_id and
sc.rn = n.number
(此处,spt_values
查询取代了数字表)
您应该能够在任何数据库中运行它,并查看该方案通常如何工作。 CROSS JOIN
为每个父行创建11行。然后我们加入使用ROW_NUMBER()
选择的前11个孩子。
我没有您的数据,所以我没有尝试使用您现有的查询来编写它。
答案 1 :(得分:0)
您需要递归查询。像这样:
;WITH tmp(i, tablename,total) AS(
SELECT ROW_NUMBER() OVER(PARTITION BY name ORDER BY name), CONVERT(varchar(MAX),name), (SELECT COUNT(*) FROM sys.columns WHERE object_id=t.object_id)
FROM sys.tables t
UNION ALL
SELECT i+1, tablename+' COPY '+CONVERT(varchar(4),i), total FROM tmp WHERE i <=20
)SELECT * FROM tmp ORDER BY 2, 1
答案 2 :(得分:0)
+1使用数字表...我没有数字表所以我将使用值构造函数创建一个例子(值构造在sql server 2008 +中工作)。
select TP.ProductID, TNum.num, Tprices.PriceID
from Product TP
INNER JOIN (select num from (values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11)) as T1(num)) TNum ON TNum.num BETWEEN 1 and 11
LEFT JOIN (select TP2.PriceID, ROW_NUMBER () OVER (PARTITION BY TP2.ProductID ORDER BY TP2.PriceID DESC) RowNum from Prices TP2) Tprices ON TNum.num = Tprices.RowNum