我想根据该表中的信息在表中插入动态行数。
我可以使用下面的代码来完成,但我想知道是否有办法避免循环。
注释掉的部分是我尝试做的最好的尝试,但它给了我一个错误: "对列" iCount"的引用在TOP,OFFSET或FETCH子句的参数中不允许使用。此处仅允许引用外部作用域中的列或独立表达式和子查询。"
DECLARE @TableX TABLE (
TDate DATE
, TType INT
, Fruit NVARCHAR(20)
, Vegetable NVARCHAR(20)
, Meat NVARCHAR(20)
, Bread NVARCHAR(20)
)
INSERT INTO @TableX VALUES
('2016-11-10',1,'Apple','Artichoke',NULL,NULL)
, ('2016-11-10',1,'Banana','Beet',NULL,NULL)
, ('2016-11-10',1,'Canteloupe','Cauliflower',NULL,NULL)
, ('2016-11-10',1,'Durian','Daikon',NULL,NULL)
, ('2016-11-10',2,NULL,NULL,'Rabbit','Rye')
, ('2016-11-10',2,NULL,NULL,'Sausage','Sourdough')
, ('2016-11-11',1,'Elderberry','Eggplant',NULL,NULL)
, ('2016-11-11',2,NULL,NULL,'Turkey','Tortilla')
, ('2016-11-11',2,NULL,NULL,'Venison','Vienna')
SELECT * FROM @TableX
DECLARE @BlankRow TABLE (
ID INT IDENTITY
, TDate DATE
, TType INT
, iCount INT
)
DECLARE @Counter1 INT = 0
, @RowCount INT
; WITH BR1
AS (
SELECT TDate, TType, COUNT(*) AS iCount
FROM @TableX
WHERE TType = 1
GROUP BY TDate, TType
)
, BR2
AS (
SELECT TDate, TType, COUNT(*) AS iCount
FROM @TableX
WHERE TType = 2
GROUP BY TDate, TType
)
INSERT INTO @BlankRow
SELECT ISNULL(BR1.TDate, BR2.TDate) AS TDate,
CASE WHEN ISNULL(BR1.iCount,0) < ISNULL(BR2.iCount,0) THEN 1 ELSE 2 END AS TType,
ABS(ISNULL(BR1.iCount,0) - ISNULL(BR2.iCount,0)) AS iCount
FROM BR1
FULL JOIN BR2
ON BR1.TDate = BR2.TDate
WHILE @Counter1 < (SELECT MAX(ID) FROM @BlankRow)
BEGIN
SET @Counter1 += 1
SET @RowCount = (SELECT iCount FROM @BlankRow WHERE ID = @Counter1)
INSERT INTO @TableX
SELECT TOP (@RowCount) tx.TDate, br.TType, NULL, NULL, NULL, NULL
FROM @TableX tx
LEFT JOIN @BlankRow br
ON tx.TDate = br.TDate
WHERE br.ID = @Counter1
END
/*INSERT INTO @TableX
SELECT TOP (tx.iCount) tx.TDate, br.TType, NULL, NULL, NULL, NULL
FROM @TableX tx
JOIN @BlankRow br
ON tx.TDate = br.TDate*/
SELECT *
FROM @TableX
ORDER BY TDate, TType,
ISNULL(Fruit,REPLICATE(CHAR(255),20)),
ISNULL(Vegetable,REPLICATE(CHAR(255),20)),
ISNULL(Meat,REPLICATE(CHAR(255),20)),
ISNULL(Bread,REPLICATE(CHAR(255),20))
我知道这些数据很愚蠢,但我的最终目标是在ReportBuilder中有两个不同的Tablix,最终会有相同的行数,所以我的组的标题出现在同一个地方。页。
答案 0 :(得分:1)
这样的事情:
declare @TableX table(TDate date
,TType int
,Fruit nvarchar(20)
,Vegetable nvarchar(20)
,Meat nvarchar(20)
,Bread nvarchar(20)
);
insert into @TableX values
('2016-11-10',1,'Apple','Artichoke',NULL,NULL)
,('2016-11-10',1,'Banana','Beet',NULL,NULL)
,('2016-11-10',1,'Canteloupe','Cauliflower',NULL,NULL)
,('2016-11-10',1,'Durian','Daikon',NULL,NULL)
,('2016-11-10',2,NULL,NULL,'Rabbit','Rye')
,('2016-11-10',2,NULL,NULL,'Sausage','Sourdough')
,('2016-11-11',1,'Elderberry','Eggplant',NULL,NULL)
,('2016-11-11',2,NULL,NULL,'Turkey','Tortilla')
,('2016-11-11',2,NULL,NULL,'Venison','Vienna');
with DataRN as
(
select *
,row_number() over (partition by TDate, TType order by TDate) rn
from @TableX
)
,RowsRN as
(
select tt.TDate
,tt.TType
,td.rn
from (select distinct TDate, TType
from @TableX
) tt
full join (select distinct t1.TDate
,row_number() over (partition by t1.TDate, t1.TType order by t1.TDate) rn
from @TableX t1
) td
on(tt.TDate = td.TDate)
)
select r.TDate
,r.TType
,d.Fruit
,d.Vegetable
,d.Meat
,d.Bread
from DataRN d
full join RowsRN r
on(d.TDate = r.TDate
and d.TType = r.TType
and d.rn = r.rn
)
order by r.TDate
,r.TType
,isnull(d.Fruit,REPLICATE(CHAR(255),20))
,isnull(d.Vegetable,REPLICATE(CHAR(255),20))
,isnull(d.Meat,REPLICATE(CHAR(255),20))
,isnull(d.Bread,REPLICATE(CHAR(255),20))
在回复您的评论时,如果您已经获得日期参考表,则可以使用其他cte
来生成您需要的完整日期列表(这些都非常有用)有用):
declare @MinDate date = (select min(TDate) from @TableX);
declare @MaxDate date = (select max(TDate) from @TableX);
with Dates as
(
select @MinDate as DateValue
union all
select dateadd(d,1,DateValue)
from Dates
where DateValue < @MaxDate
)
select DateValue
from Dates
option (maxrecursion 0);