Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/69.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 - Fatal编程技术网

Sql 识别连续或接近连续的记录

Sql 识别连续或接近连续的记录,sql,sql-server,Sql,Sql Server,我在一个包含发票编号记录的表中有一个名为invoice的列 我想确定发票编号连续或接近连续的发票 create table #temp (InvNo int) insert into #temp values (123), (124), (126), (128), (129), (133) -- For sequential SELECT [current].InvNo, [current].InvNo + 1, ISNULL([next].InvNo, 0) - [curr

我在一个包含发票编号记录的表中有一个名为invoice的列

我想确定发票编号连续或接近连续的发票

create table #temp (InvNo int)
insert into #temp values (123), (124), (126), (128), (129), (133)

-- For sequential
SELECT
   [current].InvNo,
   [current].InvNo + 1,
   ISNULL([next].InvNo, 0) - [current].InvNo as Seq
FROM
   #temp       AS [current]
LEFT JOIN
   #temp       AS [next]
      ON [next].InvNo = (SELECT MIN(InvNo) FROM #temp WHERE InvNo > [current].InvNo)
      where [current].InvNo + 1 = ISNULL([next].InvNo, 0) 

-- For not sequential
SELECT
   [current].InvNo
FROM
   #temp       AS [current]
LEFT JOIN
   #temp       AS [next]
      ON [next].InvNo = (SELECT MIN(InvNo) FROM #temp WHERE InvNo > [current].InvNo)
      where [current].InvNo + 1 <> ISNULL([next].InvNo, 0)
顺序是1,2,3,4

几乎连续的是1或2的差

我有发票号码记录

123
124
126
128
129
133

注意:发票列的数据类型为nvarchar,它也包含字母数字值,我们只能找到数字顺序记录

您可以尝试以下查询,概念是顺序号,前一张发票+1应该是下一张,否则它不是顺序的

create table #temp (InvNo int)
insert into #temp values (123), (124), (126), (128), (129), (133)

-- For sequential
SELECT
   [current].InvNo,
   [current].InvNo + 1,
   ISNULL([next].InvNo, 0) - [current].InvNo as Seq
FROM
   #temp       AS [current]
LEFT JOIN
   #temp       AS [next]
      ON [next].InvNo = (SELECT MIN(InvNo) FROM #temp WHERE InvNo > [current].InvNo)
      where [current].InvNo + 1 = ISNULL([next].InvNo, 0) 

-- For not sequential
SELECT
   [current].InvNo
FROM
   #temp       AS [current]
LEFT JOIN
   #temp       AS [next]
      ON [next].InvNo = (SELECT MIN(InvNo) FROM #temp WHERE InvNo > [current].InvNo)
      where [current].InvNo + 1 <> ISNULL([next].InvNo, 0)
结果如下所示


仅适用于数字的InvNo

可以在[不]存在的地方使用

示例代码段:

返回:

但是使用窗口函数也可以。 例如,使用滞后和超前

然后查询将如下所示:

SELECT Id, InvNo
FROM
(
    SELECT Id, InvNo
    , CAST(InvNo AS INT) AS InvNum
    , CAST(LAG(InvNo) OVER (ORDER BY CAST(InvNo AS INT) ASC) AS INT) AS prevInvNum
    , CAST(LEAD(InvNo) OVER (ORDER BY CAST(InvNo AS INT) ASC) AS INT) AS nextInvNum
    FROM #SemiSequenceTest  t
    WHERE t.InvNo LIKE '[0-9]%[0-9]'
      AND ISNUMERIC(t.InvNo) = 1
) q
WHERE (InvNum <= prevInvNum + 2 OR InvNum >= nextInvNum - 2);

你试过什么了吗?对于EXISTS操作符来说似乎是一个简单的工作。或者您可以使用LAG;有很多参考资料。LAG将相互比较,我有大量数据。我不确定EXISTS运算符将如何工作。您想要什么结果?感谢您的回复!!但在我的表中,invoice列的数据类型是nvarchar,它包含字母数字值,所以加法和减法运算符不起作用here@user9185088在这种情况下,我不知道,我已经根据您提供的样本数据准备了示例。
SELECT Id, InvNo
FROM
(
    SELECT Id, InvNo
    , CAST(InvNo AS INT) AS InvNum
    , CAST(LAG(InvNo) OVER (ORDER BY CAST(InvNo AS INT) ASC) AS INT) AS prevInvNum
    , CAST(LEAD(InvNo) OVER (ORDER BY CAST(InvNo AS INT) ASC) AS INT) AS nextInvNum
    FROM #SemiSequenceTest  t
    WHERE t.InvNo LIKE '[0-9]%[0-9]'
      AND ISNUMERIC(t.InvNo) = 1
) q
WHERE (InvNum <= prevInvNum + 2 OR InvNum >= nextInvNum - 2);