【问题标题】:Use WHERE IN but report missing rows使用 WHERE IN 但报告缺失的行
【发布时间】:2018-01-12 16:20:55
【问题描述】:

我需要根据键值列表 (EIBItemID) 从 SQL 表中报告数据,我可以将它们粘贴到这样的查询中

select * 
from dbo.SupplyChain_1000469 
where EIBItemID in (421290,421316, and so on)

但是,如果返回的结果比我提供的要少,我需要一种快速的方法来报告表中不存在 EIBItemID 的位置,我可以搜索数千个这样的键,但希望避免每次都创建表对于每个列表,更容易将它们粘贴到查询中。

我尝试将记录放入临时表中,然后像这样进行连接

DROP TABLE #EIBItemIDs

CREATE TABLE #EIBItemIDs (EIBItemID INT)

INSERT INTO #EIBItemIDs (EIBItemID) 
VALUES (00481771), (00481772), (00481773)

SELECT v.EIBItemID
FROM #EIBItemIDs v
LEFT JOIN dbo.SupplyChain_1799 t ON t.EIBItemID = v.EIBItemID
WHERE t.EIBItemID IS NULL

只查找丢失的行,但有没有办法使用第一个查询但报告每一行(如果键不存在,则只显示空值)?

【问题讨论】:

  • 带空检查的左连接是查找不存在的行的最佳方法。您可以将第一个查询与 EXCEPT 运算符一起使用,但它不会像您的第二个查询那样快
  • @sparrow 不是说先把我的列表放到表格里吗?
  • 如果我理解正确,您正在将您的列表输入到一个临时表中,这样您就不必重复输入它。我看不出有什么问题。很可能,这个列表也来自另一个表,它可以由另一个 select 语句或查询中的不同连接来定义。按钮行是,左外连接和NULL条件检查,是最快的得到结果的方法。如何定义 ID 列表是另一回事。您关心的是定义列表还是查询本身?
  • 该列表通常作为电子表格中的列提供,我们可以将这些作为新表导入 SQL,但将列复制到查询中会更快

标签: sql where


【解决方案1】:

没有办法使用IN。但是您不必使用单独的表。 SQL Server(我假设您根据语法使用它)允许您在 FROM 子句中创建一个表:

select *
from (values (421290), (421316), . . .
     ) v(EIBItemID)
where not exists (select 1 from dbo.SupplyChain_1000469 sc where sc.EIBItemID = v.EIBItemID) ;

【讨论】:

    【解决方案2】:

    最终使用一个范围来保存我的列表中的最低和最高数字,然后加入该范围,以便它报告实际数据中的范围和匹配项,如果在数据中找不到,则为 NULL。我使用 Habeeb 在这篇文章中的回复来获取范围表 (How to generate a range of numbers between two numbers?)

    DECLARE @min bigint, @max bigint
    SELECT @Min=7208901 ,@Max=8008170
    ;
    DROP TABLE #missingIDs
    
    Create Table #missingIDs(
    ItemID numeric(8,0)
    )
    INSERT INTO #missingIDs (ItemID)
    SELECT TOP (@Max-@Min+1) @Min-1+row_number() over(order by t1.number) as ItemID
    FROM master..spt_values t1 
    CROSS JOIN master..spt_values t2
    ;
    with results  (SCID, EIBItemID, SubmissionDate, [HandoverDate], uploaddate,[Product],[Format],[Class],[Postcode],[DPS],[Status],[MMD_FileName], [Spare8] ,[ManifestID],[barcode]) As
    (
    SELECT EIBItemID, SubmissionDate, [HandoverDate], uploaddate,
        [Product]
        ,[Format]
        ,[Class]
        ,[Postcode]
        ,[DPS]
        ,[Status]
        ,[MMD_FileName], [Spare8] ,[ManifestID] ,[barcode]
    FROM SupplyChain_1000468 with (nolock)
    )
    select t.SCID,v.ItemID,t.SubmissionDate, t.[HandoverDate], t.uploaddate,t.[Product],t.[Format],t.[Class],t.[Postcode],t.[DPS],t.[Status],t.[MMD_FileName],t.[Spare8],t.[ManifestID],t.[barcode]
    from #missingIDs v
    left join results t on t.EIBItemID = v.ItemID
    where v.itemid in (<list of itemids(comma separated)>
    )
    order by v.itemid asc
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-11-09
      • 2014-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-02
      相关资源
      最近更新 更多