我如何从表中找到缺失值?

时间:2016-03-29 11:30:34

标签: sql sql-server-2008

我有一张像
一样的桌子 enter image description here
因为有N个值,所以如何找到与给定

相同格式的ExciseInvoiceNo
DECLARE @temp table
(val int)
insert INTO @temp([val])
SELECT  CONVERT(INT, (case when CHARINDEX('/', EXCISEINVOICENO) > 0 Then 
                 cast(substring(EXCISEINVOICENO,1,len(EXCISEINVOICENO) - 3) as int)
            else Cast(EXCISEINVOICENO as Int) end)  ) as ExciseInvoiceIndex
FROM  tblExciseInvoice
 WHERE      CompYearID=109
   AND (InvoiceDate BETWEEN '10/1/2015 12:00:00 AM' AND '03/30/2016 11:59:59 PM')  
 select (select isnull(max(val)+1,1) from @temp where val < md.val) as [from],
     md.val - 1 as [to]
 from @temp md
  where md.val != 1 and not exists (
        select 1 from @temp md2 where md2.val = md.val - 1)

我正在尝试这个,但没有得到正确的合成结果

1 个答案:

答案 0 :(得分:0)

假设缺少您的意思是从发票的第一次出现到发票的最大出现次数。缺少是介于两者之间的任何事情......

也许您的发票从1/15开始或者在某些时候开始,然后我们需要为4个职位提供LPAD零。或者它可以达到多少......

Working SQL FIDDLE

这是一种方法

  1. 将表格加入自身
  2. 但在发票号左侧使用+1的加入条件
  3. 并确保正确的部件匹配。
  4. 此方法与超前/滞后窗口函数的关系是它无法使用索引,因为我们正在操作字符串,因此在大型数据集上可能会很慢。

    SELECT A.ExciseInvoiceNO, B.ExciseInvoiceNo,
    case when B.ExciseInvoiceNo is null then
    cast(left(A.ExciseInvoiceNO,4)+1 as varchar(20)) + right(A.ExciseInvoiceNO,3) end
    as MissingInvoices
    FROM foo A
    LEFT JOIN Foo  B
     on Left(A.ExciseInvoiceNO,4)+1 = left(B.ExciseInvoiceNO,4)
     and right(A.ExciseInvoiceNO,3)  = right(B.ExciseInvoiceNO,3)
    WHERE case when B.ExciseInvoiceNo is null then
    cast(left(A.ExciseInvoiceNO,4)+1 as varchar(20)) + right(A.ExciseInvoiceNO,3) end is not null
    

    使用窗口函数的方法

    2nd Working Fiddle

    此窗口功能可让您查看exciseInvoiceNo排序的下一条记录,然后比较结果。我们可能必须先将权利分为右边3个字符然后左边,但不理解你的InvoiceNumber格式的性质我不能确定。我使用CTE(公用表表达式)将下一个记录发票号的值存储在一个数据集中,然后我们使用字符串操作。

    with cte as (
    Select ExciseInvoiceNO Ino, 
    Lead(ExciseInvoiceNo,1) over (order by ExciseInvoiceNo) compare
    from foo A)
    
    Select case when left(INo,4)+1 = left(compare,4)
                and  right(Ino,3)  = right(compare,3)
           then Null
           else cast(left(INo,4)+1 as varchar(20)) + right(Compare,3)
           end as MissingInvoiceNo
    from cte
    WHERE case when left(INo,4)+1 = left(compare,4)
                and right(Ino,3)  = right(compare,3)
          then Null
          else cast(left(INo,4)+1 as varchar(20)) + right(Compare,3) end
      is not null