Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 查找缺少的周期并确定之前是否连续_Sql_Sql Server_Tsql - Fatal编程技术网

Sql 查找缺少的周期并确定之前是否连续

Sql 查找缺少的周期并确定之前是否连续,sql,sql-server,tsql,Sql,Sql Server,Tsql,我目前正在制定一项要求,以找到缺失的时段,然后确定它在缺失时段之前是否是连续的 下面是我的示例表结构 第一步:在下面的样本表中,查看过去6个月的2014年7月-2014年12月。它失踪了两个月8号和11号。就拿第一个例子来说 第二步:从一审失踪的6个月前返回——2014年2月-2014年7月——看看他们是否失踪了任何一个月。如果否,所有内容都是连续的-选择/包括此记录如果是,缺少几个月-不要选择此记录 Year Month 2014 1 2014 2 2014 3 2

我目前正在制定一项要求,以找到缺失的时段,然后确定它在缺失时段之前是否是连续的

下面是我的示例表结构

第一步:在下面的样本表中,查看过去6个月的2014年7月-2014年12月。它失踪了两个月8号和11号。就拿第一个例子来说

第二步:从一审失踪的6个月前返回——2014年2月-2014年7月——看看他们是否失踪了任何一个月。如果否,所有内容都是连续的-选择/包括此记录如果是,缺少几个月-不要选择此记录

Year   Month   
2014    1
2014    2
2014    3
2014    4
2014    5
2014    6
2014    7
2014    9
2014    10
2014    12
我可以按行号选择最后6条记录和分区,并查看是否缺少任何记录。但我不知道如何找到它的连续性,也选择了缺失的时期

我正在尝试在Transact-SQL中进行尽可能多的过滤,以便我可以专注于c上的其他验证

我创建的用于查找第一个期间缺失的查询未完成

SELECT f.TYEAR,f.TMONTH, f.TMONTH+1 AS MISSING FROM #TEMPTABLE AS F
LEFT OUTER JOIN #TEMPTABLE AS F2 ON f.TMONTH+1 = f2.TMONTH
WHERE f2.TAXPERIOD IS NULL

注:上述示例可以跨越两个日历年。2013 mm-2014 mm

我认为下面的代码应该可以工作,尽管我没有正确地测试它。但你会明白的-

DECLARE @TmpBaseTable TABLE ([Year] SMALLINT, [Month] TINYINT)
DECLARE @TmpSixMonthTable TABLE (TmpYear SMALLINT, TmpMonth TINYINT)
DECLARE @TmpDate DATE
DECLARE @MissingYear SMALLINT
DECLARE @MissingMonth TINYINT
DECLARE @TmpCount TINYINT


INSERT INTO @TmpBaseTable ([Year], [Month])
SELECT 2014, 1 UNION ALL
SELECT 2014, 2 UNION ALL
SELECT 2014, 3 UNION ALL
SELECT 2014, 4 UNION ALL
SELECT 2014, 5 UNION ALL
SELECT 2014, 6 UNION ALL
SELECT 2014, 7 UNION ALL
SELECT 2014, 8 UNION ALL
SELECT 2014, 9 UNION ALL
SELECT 2014, 10 UNION ALL
SELECT 2014, 11 UNION ALL
SELECT 2014, 12 UNION ALL
SELECT 2015, 1 UNION ALL
SELECT 2015, 3 UNION ALL
SELECT 2015, 4

SELECT TOP 1 @TmpDate = CAST(CAST(tmpYear AS VARCHAR) + '-' + CAST(tmpMonth AS VARCHAR) + '-' + CAST(1 AS VARCHAR) AS DATE)
FROM
(
    SELECT ROW_NUMBER() OVER(ORDER BY [Year], [Month]) AS RowID, [Month] AS tmpMonth, [Year] AS tmpYear
    FROM @TmpBaseTable
)
tmp ORDER BY RowID DESC

INSERT INTO @TmpSixMonthTable  (TmpMonth, TmpYear)
SELECT DATEPART(MONTH, DATEADD (MONTH, -5, @TmpDate)), DATEPART(YEAR, DATEADD (MONTH, -5, @TmpDate)) UNION ALL
SELECT DATEPART(MONTH, DATEADD (MONTH, -4, @TmpDate)), DATEPART(YEAR, DATEADD (MONTH, -4, @TmpDate)) UNION ALL
SELECT DATEPART(MONTH, DATEADD (MONTH, -3, @TmpDate)), DATEPART(YEAR, DATEADD (MONTH, -3, @TmpDate)) UNION ALL
SELECT DATEPART(MONTH, DATEADD (MONTH, -2, @TmpDate)), DATEPART(YEAR, DATEADD (MONTH, -2, @TmpDate)) UNION ALL
SELECT DATEPART(MONTH, DATEADD (MONTH, -1, @TmpDate)), DATEPART(YEAR, DATEADD (MONTH, -1, @TmpDate)) UNION ALL
SELECT DATEPART(MONTH, DATEADD (MONTH, -0, @TmpDate)), DATEPART(YEAR, DATEADD (MONTH, -0, @TmpDate))

SELECT TOP 1 @MissingMonth = tmpSix.TmpMonth, @MissingYear = tmpSix.TmpYear FROM @TmpSixMonthTable tmpSix
LEFT OUTER JOIN @TmpBaseTable tmpBase ON tmpSix.TmpMonth = tmpBase.[Month] AND tmpSix.TmpYear = tmpBase.[Year]
WHERE tmpBase.[Year] IS NULL

SET @TmpDate = CAST(CAST(@MissingYear AS VARCHAR) + '-' + CAST(@MissingMonth AS VARCHAR) + '-' + CAST(1 AS VARCHAR) AS DATE)

DELETE FROM @TmpSixMonthTable

INSERT INTO @TmpSixMonthTable  (TmpMonth, TmpYear)
SELECT DATEPART(MONTH, DATEADD (MONTH, -6, @TmpDate)), DATEPART(YEAR, DATEADD (MONTH, -6, @TmpDate)) UNION ALL
SELECT DATEPART(MONTH, DATEADD (MONTH, -5, @TmpDate)), DATEPART(YEAR, DATEADD (MONTH, -5, @TmpDate)) UNION ALL
SELECT DATEPART(MONTH, DATEADD (MONTH, -4, @TmpDate)), DATEPART(YEAR, DATEADD (MONTH, -4, @TmpDate)) UNION ALL
SELECT DATEPART(MONTH, DATEADD (MONTH, -3, @TmpDate)), DATEPART(YEAR, DATEADD (MONTH, -3, @TmpDate)) UNION ALL
SELECT DATEPART(MONTH, DATEADD (MONTH, -2, @TmpDate)), DATEPART(YEAR, DATEADD (MONTH, -2, @TmpDate)) UNION ALL
SELECT DATEPART(MONTH, DATEADD (MONTH, -1, @TmpDate)), DATEPART(YEAR, DATEADD (MONTH, -1, @TmpDate))


SELECT @TmpCount = COUNT(1) FROM @TmpSixMonthTable tmp1
INNER JOIN @TmpBaseTable tmp2 ON tmp1.TmpMonth = tmp2.[Month] AND tmp1.TmpYear = tmp2.[Year]

IF(@TmpCount = 6)
BEGIN
    SELECT tmp2.[Month], tmp2.[Year] FROM @TmpSixMonthTable tmp1
    INNER JOIN @TmpBaseTable tmp2 ON tmp1.TmpMonth = tmp2.[Month] AND tmp1.TmpYear = tmp2.[Year]
END

还有比这更聪明的方法:

这一个已经过测试,我已经花了一些时间,请告诉我您是否对结果满意,如果满意,请投票,干杯:-PS:表dbo.Months\u和\u Years包含您缺少的两个月的数据

            CREATE TABLE dbo.Test_Table  ( 
            [Year] SMALLINT,
            [Month] TINYINT
            );

            INSERT INTO dbo.Test_Table
            VALUES 
            (2014, 1),
            (2014, 2),
            (2014, 3),
            (2014, 4),
            (2014, 5),
            (2014, 6),
            (2014, 7),
            (2014, 9),
            (2014, 10),
            (2014, 12);




            DECLARE @MinValue TINYINT = 1
            DECLARE @MaxValue TINYINT = 100

            WHILE @MinValue < = @MaxValue

            BEGIN
            DECLARE @Missing_Month TINYINT = (

                        SELECT TOP 1 A.RowID
                        FROM (
                        SELECT DENSE_RANK() OVER ( ORDER BY [month])  AS RowID ,
                         *
                        FROM dbo.Test_Table
                        ) AS A
                        WHERE A.RowID <> A.[Month]
                        )
            SELECT  @Missing_Month

            IF @Missing_Month IS NULL

            BREAK

            ELSE
            INSERT INTO dbo.Test_Table
            VALUES (2014, @Missing_Month)

            SET @MinValue = @MinValue + 1

            END


            -- Check your results ---
            SELECT A.*
            FROM dbo.Test_Table AS A
LEFT JOIN dbo.Months_and_Years AS B  ON A.[Month] = B.[Month]
            WHERE B.[Month] IS NULL;

请添加您为实现此目的而厌倦的任何sql查询。还要添加sqlfiddle您使用的是哪个版本的sql server?对于这类问题,这将非常重要。如果在过去六个月内什么都没有丢失,该怎么办?Sql server 2014。如果在过去6个月内没有遗漏任何东西,那么我们就不必进行第二步。我们可以忽略这个记录。通过一个单独的月份表,可能最容易找到缺少的周期。要查看前6个月,您可以使用LAG函数HI Kartic感谢您的回复。我不确定这是否会处理纳税年度发生切换的情况,即2013年某个月到2014年某个月,我认为这只适用于一个日历年。我会更新我的疑问,我应该在我的原始问题中提到,嗨,克劳迪奥。示例可以是b/w两个不同的日历年。我在我的问题中添加了一个注释,即2013 mm-2014 mm