Sql 使用多个CTE和一个INSERT语句。[错误:超过列列表中指定的列数]

Sql 使用多个CTE和一个INSERT语句。[错误:超过列列表中指定的列数],sql,sql-server,database,sql-server-2016,Sql,Sql Server,Database,Sql Server 2016,我的CTE1和CTE2如下。CTE2显示错误 CTE2的列数超过列列表中指定的列数 我想知道我做错了什么。这不能是因为Insert语句的列数比CTE2多,因为CTE1以前工作正常。CTE1和CTE2都使用不同的表。这就是问题所在吗 如果删除CTE2NewRoomCost、NewQuantity中的参数,则会得到错误 没有为CTE2的第3列指定列 下面是我尝试的代码。任何帮助都将不胜感激 CREATE PROCEDURE dbo.SpTransactionGenerate AS BEGIN SET

我的CTE1和CTE2如下。CTE2显示错误

CTE2的列数超过列列表中指定的列数

我想知道我做错了什么。这不能是因为Insert语句的列数比CTE2多,因为CTE1以前工作正常。CTE1和CTE2都使用不同的表。这就是问题所在吗

如果删除CTE2NewRoomCost、NewQuantity中的参数,则会得到错误

没有为CTE2的第3列指定列

下面是我尝试的代码。任何帮助都将不胜感激

CREATE PROCEDURE dbo.SpTransactionGenerate
AS
BEGIN
SET NOCOUNT ON

    DECLARE @MinReservationId INT = (SELECT MIN(f.ReservationId) FROM dbo.Reservation AS f)
    DECLARE @MaxReservationId INT = (SELECT MAX(f.ReservationId) FROM dbo.Reservation AS f)

    DECLARE @FirstSeasonEndDate DATE= '2018-02-13';
    DECLARE @SecondSeasonEndDate DATE='2018-02-14';
    DECLARE @ThirdSeasonEndDate DATE='2018-12-31';

    WHILE @MinReservationId<=@MaxReservationId
    BEGIN   
        WITH CTE1(ServiceId,ServiceRate,Quantity) AS 
        (
           SELECT ServiceId,
                  ServiceRate,
                  ABS(CHECKSUM(NEWID())%3) + 1 AS Quantity 
           FROM dbo.[Service]                              
        ),
        CTE2(NewRoomCost,NewQuantity) AS 
        (
           SELECT 
                (SELECT roomRate.RoomCost FROM dbo.RoomRate as roomRate WHERE roomRate.RoomTypeId=
                (SELECT room.RoomTypeId FROM dbo.Room as room
                JOIN dbo.Reservation as res ON res.RoomId=room.RoomId WHERE res.ReservationId=@MinReservationId
                AND roomRate.SeasonId=(
                CASE WHEN (SELECT resv.CheckInDate FROM dbo.Reservation as resv WHERE resv.ReservationId=@MinReservationId)<=@FirstSeasonEndDate
                THEN (SELECT sea.SeasonId FROM dbo.Season as sea WHERE sea.SeasonEndDate=@FirstSeasonEndDate)
                WHEN (SELECT resv.CheckInDate FROM dbo.Reservation as resv WHERE resv.ReservationId=@MinReservationId)<=@SecondSeasonEndDate
                THEN (SELECT sea.SeasonId FROM dbo.Season as sea WHERE sea.SeasonEndDate=@SecondSeasonEndDate)
                ELSE (SELECT sea.SeasonId FROM dbo.Season as sea WHERE sea.SeasonEndDate=@ThirdSeasonEndDate) END
                )
                )) AS NewRoomCost,

                DATEDIFF(DAY,(SELECT r.CheckinDate FROM dbo.Reservation AS r WHERE r.ReservationId=@MinReservationId), (SELECT r.CheckOutDate FROM dbo.Reservation AS r WHERE r.ReservationId=@MinReservationId)) AS NewQuantity,                                                  
        )

        INSERT INTO dbo.[Transaction]
        (
            ReservationId,
            ServiceId,
            Rate,
            Quantity,
            Amount              
        )   
        SELECT 
            @MinReservationId,
            ServiceId,
            ServiceRate,
            Quantity,
            ServiceRate*Quantity
            FROM CTE1
            UNION
        SELECT 
            @MinReservationId,
            NULL,
            NewRoomCost,
            NewQuantity,
            NewRoomCost*NewQuantity
            FROM CTE2

        SELECT @MinReservationId=@MinReservationId+1    
    END
END

更新:由于CTE2中有一个额外的逗号而导致错误。对不起,我提出了不必要的问题

因为第二个CTE定义了两列:

CTE2(NewRoomCost,NewQuantity) AS
但是select语句返回3

(SELECT roomRate.RoomCost FROM...

DATEDIFF(DAY,(SELECT r.CheckinDate...

(SELECT r.CheckOutDate FROM dbo.Reservation...
CTE2中的问题是,在这一行的末尾有一个额外的逗号:

DATEDIFF(DAY,(SELECT r.CheckinDate FROM dbo.Reservation AS r WHERE r.ReservationId=@MinReservationId), (SELECT r.CheckOutDate FROM dbo.Reservation AS r WHERE r.ReservationId=@MinReservationId)) AS NewQuantity, 

旁注:我建议以后不要写明确的列名,而应该像使用as关键字那样命名它们。它只是提供了更大的灵活性。

不是从dbo.Reservation中选择r.CheckOutDate。。。包含在DATEDIFF datepart,startdate,enddate中我相信你在DATEDIFF的末尾只有一个额外的逗号。@MK_u是的,感觉很愚蠢:|我不能删除这个问题,因为重复删除会阻止我问未来的问题。啊!!我只是想在问题中编辑它。@SudeepShrestha-没关系,像这样的错误很容易发生。我建议我写一个答案,你把它标记为解决方案,这样就可以结案了为什么是ctes和工会。直接插入两个。@Papazzo,因为我需要在同一select语句中使用最近插入的速率和数量的值。如果有更好的方法,请指导我但是您没有使用第二个cte中第一个cte的值。@狗仔队是我使用CTE1I放弃的原因。CTE在这里没有任何价值。你可以直接插入。