SELECT INTO出现意外结果

时间:2016-04-12 07:06:20

标签: sql-server tsql

我在MSSQL中创建了一个表值函数,它接收了2个paramateres 1.结束日期 2.返回的周数 生成一个包含周开始日期的日期表。

PERIOD表只是一个包含1列的表(称为pPeriod),所有日期都在' 19971229'之间。和' 20201231'

CREATE FUNCTION [dbo].[Get_Week_Rank]
(   
    -- Add the parameters for the function here
    @PERIOD_END DATETIME,
    @NUM_WEEKS INT
)
RETURNS TABLE 
AS
RETURN 
(
    SELECT A.PPERIOD TY_PPERIOD, B.PPERIOD TY_PWKSTART, DATEADD(YY, -1, A.PPERIOD) LY_PPERIOD, DATEADD(YY, -1, B.PPERIOD) LY_PWKSTART, B.CRNK WEEK_RANK  FROM (
        SELECT PPERIOD, ROW_NUMBER() OVER (ORDER BY PPERIOD) CRNK FROM PERIODS
            WHERE PPERIOD BETWEEN DATEADD(WW, @NUM_WEEKS - 1, @PERIOD_END)  + 1 AND @PERIOD_END
        ) AS A
        JOIN (
            SELECT PPERIOD, ROW_NUMBER() OVER (ORDER BY CRNK % 7) CRNK FROM (
                SELECT PPERIOD, ROW_NUMBER() OVER (ORDER BY PPERIOD) CRNK FROM PERIODS
                    WHERE PPERIOD BETWEEN DATEADD(WW, @NUM_WEEKS, @PERIOD_END)  +  1 AND @PERIOD_END
                ) AS A
                WHERE CRNK % 7 = 1
            ) AS B ON (A.CRNK - 1)/7 = B.CRNK
)

我注意到当@NUM_WEEKS介于-1和-130之间时,运行此查询时结果是正确的:

SELECT * INTO #WEEKS FROM GET_WEEK_RANK('20160401', -104)
SELECT * FROM #WEEKS ORDER BY 1

但是,任何低于-130的数字(例如-156,-208),返回的结果都是错误的。

Wrong results

您可以看到TY_PWKSTART全部乱七八糟,与TY_PPERIOD不同步。 如果我直接运行查询,结果返回正常:

SELECT * FROM GET_WEEK_RANK('20160401', -140)

可能是什么问题?我正在使用Microsoft SQL Server 2014

编辑:发布结果图像 如您所见,两个查询基本上都做同样的事情,但返回的结果是不同的。使用SELECT INTO时第一个查询中pWkStart的顺序是错误的。

错误的结果:

SELECT * INTO #WEEK_WRONG FROM GET_WEEK_RANK('20160410', -140)
SELECT * FROM #WEEK_WRONG ORDER BY 1

WRONG RESULTS

正确的结果:

CREATE TABLE #WEEK_CORRECT (TY_PPERIOD DATETIME, TY_PWKSTART DATETIME, LY_PPERIOD DATETIME, LY_PWKTART DATETIME, WEEK_RANK INT)
INSERT INTO #WEEK_CORRECT
SELECT * FROM GET_WEEK_RANK('20160410', -140)
SELECT * FROM #WEEK_CORRECT ORDER BY 1

CORRECT RESULTS

EDIT2: 事实证明我的初始查询产生了意想不到的结果。我修复了我的查询并设法从SELECT INTO和INSERT INTO获得一致的结果。 只需在这里分享代码:

CREATE FUNCTION [dbo].[Get_Week_Rank]
(   
    @PERIOD_END DATETIME,
    @NUM_WEEKS INT
)
RETURNS TABLE 
AS
RETURN 
(
    SELECT A.PPERIOD TY_PPERIOD, B.PPERIOD TY_PWKSTART, DATEADD(YY, -1, A.PPERIOD) LY_PPERIOD, DATEADD(YY, -1, B.PPERIOD) LY_PWKSTART, B.CRNK + 1 WEEK_RANK  FROM (
            SELECT PPERIOD, (ROW_NUMBER() OVER (ORDER BY PPERIOD)-1)/7 CRNK FROM PERIODS
                WHERE PPERIOD BETWEEN DATEADD(WW, @NUM_WEEKS, @PERIOD_END)  + 1 AND @PERIOD_END
        ) AS A
        JOIN (
            SELECT PPERIOD, ROW_NUMBER() OVER (ORDER BY PPERIOD)-1 CRNK FROM (
                SELECT PPERIOD , ROW_NUMBER() OVER (PARTITION BY CRNK ORDER BY CRNK) CRNK FROM (
                    SELECT PPERIOD, (ROW_NUMBER() OVER (ORDER BY PPERIOD)-1)/7 CRNK FROM PERIODS
                        WHERE PPERIOD BETWEEN DATEADD(WW, @NUM_WEEKS, @PERIOD_END)  +  1 AND @PERIOD_END
                    ) AS A
                ) AS A
                WHERE CRNK = 1
            ) AS B ON A.CRNK = B.CRNK
)

1 个答案:

答案 0 :(得分:1)

您的查询的这部分内容已被破坏:

SELECT PPERIOD, ROW_NUMBER() OVER (ORDER BY CRNK % 7) CRNK FROM (
    ...
) AS A
WHERE CRNK % 7 = 1

由于where子句确定CRNK % 7等于1ROW_NUMBER()表达式可以按任意顺序 1 自由分配行号。我猜你仍然希望在{em> order 中分配行号,其中PPERIODCRNK值有效,因此表达式应改为:

SELECT PPERIOD, ROW_NUMBER() OVER (ORDER BY CRNK) CRNK FROM (
    ...
) AS A
WHERE CRNK % 7 = 1

1 由于您没有在ORDER BY中提供足够的表达式来明确指定 的行号,因此无法保证分配给每个的值行。