我正在编写一个SQL语句,它将客户交付的详细信息输出到一个漂亮的转发器网格中。但是,基于customers表中的字段(使用整数确定行数),我需要能够生成那些具有完全相同细节的行。
I.E:交付有一行,但根据该客户的customers表中的数字,需要在SQL中多次输出同一行。
有什么想法吗?很抱歉,如果它有点令人困惑,我知道这听起来很愚蠢,但是从正在为该交付生成的SQL'标签',可能需要多个标签。
答案 0 :(得分:3)
这是一种方法,利用“数字”表,您可以创建并填充从1到n的数字(一次性过程)
SELECT d.*
FROM Delivery d
JOIN Customer c ON d.CustomerID = c.ID
JOIN @Numbers n ON c.NumberField >= n.Num
e.g。基本的例子
DECLARE @T1 TABLE (ID INTEGER)
DECLARE @T2 TABLE (ID INTEGER, RowCnt INTEGER)
INSERT @T1 VALUES (1)
INSERT @T1 VALUES (2)
INSERT @T1 VALUES (3)
INSERT @T1 VALUES (4)
INSERT @T2 VALUES (1,1)
INSERT @T2 VALUES (2,2)
INSERT @T2 VALUES (3,4)
DECLARE @Numbers TABLE (Num INTEGER)
INSERT @Numbers VALUES(1)
INSERT @Numbers VALUES(2)
INSERT @Numbers VALUES(3)
INSERT @Numbers VALUES(4)
INSERT @Numbers VALUES(5)
SELECT t1.*
FROM @T1 t1
JOIN @T2 t2 ON t1.ID = t2.ID
JOIN @Numbers n ON t2.RowCnt >= n.Num
<强>更新强>
如果您不想创建物理数字表,则可以(对于数字1-2048)使用这样的spt_values:
SELECT t1.*
FROM @T1 t1
JOIN @T2 t2 ON t1.ID = t2.ID
JOIN spt_values n ON t2.RowCnt >= n.Num AND n.type='P'
答案 1 :(得分:3)
AdaTheDev的扩展答案。使用CTE创建数字表。
with Numbers(Num)
as
(
select 1 as Num
union all
select (Num + 1) as Num
from Numbers
where Num < 1000
)
select t1.*
from @T1 t1
join @T2 t2 on t1.ID = t2.ID
join Numbers n on t2.RowCnt >= n.Num option(maxrecursion 1000)
答案 2 :(得分:0)
我认为这里运作良好的是递归CTE。在我的示例中,我使用一些仅用于演示的示例数据来创建表变量。 DECLARE @RepeatedLevel = 3;
及以后的部分是查询本身。
-- Sample table variables are purely for demonstration.
DECLARE @Customer TABLE
(
ID INT IDENTITY(1,1)
, Name VARCHAR(25)
)
DECLARE @Delivery TABLE
(
ID INT IDENTITY(1,1)
, CustomerID INT
, DeliveryDate DATE
);
INSERT INTO @Customer
VALUES ('Jeremy'), ('Chris'), ('Sachin'), ('AdaTheDev');
INSERT INTO @Delivery
VALUES (1, '20100602')
, (2, '20100726')
, (2, '20110103')
, (3, '20090401')
, (3, '20100214')
, (3, '20100726')
, (4, '20100713')
, (4, '20100719')
, (4, '20100813')
, (4, '20101028');
DECLARE @RepeatedLevel INT = 3;
WITH DeliverysRepeated AS
(
SELECT
Customer.Name
, Delivery.DeliveryDate
, 1 AS RecursionLevel
FROM @Customer Customer
INNER JOIN @Delivery Delivery
ON Delivery.CustomerID = Customer.ID
UNION ALL
SELECT
DeliverysRepeated.Name
, DeliverysRepeated.DeliveryDate
, DeliverysRepeated.RecursionLevel + 1 AS RecursionLevel
FROM DeliverysRepeated
WHERE DeliverysRepeated.RecursionLevel < @RepeatedLevel
)
SELECT
DeliverysRepeated.Name
, DeliverysRepeated.DeliveryDate
FROM DeliverysRepeated
ORDER BY Name, DeliveryDate DESC