我可以使用表中的值将动态行数插入表中吗?

时间:2016-10-11 23:24:10

标签: tsql sql-server-2012 ssrs-2012

我想根据该表中的信息在表中插入动态行数。

我可以使用下面的代码来完成,但我想知道是否有办法避免循环。

注释掉的部分是我尝试做的最好的尝试,但它给了我一个错误: "对列" 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,最终会有相同的行数,所以我的组的标题出现在同一个地方。页。

1 个答案:

答案 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);