【问题标题】:Find the missing group entry in sql server在 sql server 中查找缺少的组条目
【发布时间】:2020-08-04 07:06:32
【问题描述】:

我有下表:

 Declare @t table (Name nvarchar(80))
 
 Insert into @t values 
 
 ('ABC:CE')
 ,('ABC:LI')    
 ,('ABC:XP')    
 ,('ABD:CE')    
 ,('ABD:LI')    
 ,('ABE:LI')    
 ,('ABE:XP')    
 ,('ABF:XP')

我有 3 个类别 CE、LI、XP。我想检查名称中缺少哪个组。

我试过下面的查询:

 select  SUBSTRING(Name,1,charindex(':',Name)-1),count(1) as grplist from @t
 group by SUBSTRING(Name,1,charindex(':',Name)-1)
 having count(1) <3

预期输出:

Name    
ABD:XP  
ABE:CE  
ABF:LI  
ABF:CE

你们能帮我看看我哪里出错了吗:

【问题讨论】:

    标签: sql sql-server tsql sql-server-2008


    【解决方案1】:

    试试这个:

     Declare @t table (Name nvarchar(80))
     
     Insert into @t values 
     
     ('ABC:CE')
     ,('ABC:LI')    
     ,('ABC:XP')    
     ,('ABD:CE')    
     ,('ABD:LI')    
     ,('ABE:LI')    
     ,('ABE:XP')    
     ,('ABF:XP');
    
    
    WITH DataSource ([group], [category]) AS
    (
        SELECT SUBSTRING([Name], 1, CHARINDEX(':', [Name]) - 1)
              ,SUBSTRING([Name], CHARINDEX(':', [Name]) + 1, 100)
        FROM @t
    )
    SELECT DISTINCT G.[group], C.[category]
    FROM DataSource G
    CROSS APPLY
    (
        SELECT DISTINCT [category]
        FROM DataSource
    ) C
    WHERE NOT EXISTS
    (
        SELECT 1 
        FROM DataSource DS
        WHERE DS.[group] = G.[group]
            AND DS.[category] = C.[category]
    )
    

    【讨论】:

    • 可能SELECT category FROM (VALUES ('CE'), ('LI'), ('XP')) v (category) 而不是SELECT DISTINCT [category] FROM DataSource 在这里更合适(例如表@t 只有一行('ABC:CE'))。如果我没记错的话,VALUES() 表值构造函数是在 SQL Server 2008 中引入的。
    • @Zhorov 如果类别已知,则有意义。它肯定会表现得更好。
    【解决方案2】:

    您要选择表中的值。为此,您必须首先创建这些值。您可以通过交叉连接来做到这一点:

    select n.name + ':' + c.category as missing
    from (select distinct substring(name, 1, charindex(':', name) - 1) as name from @t) n
    cross join (values ('CE'), ('LI'), ('XP')) c(category)
    except
    select name from @t
    order by missing;
    

    演示:http://www.sqlfiddle.com/#!18/c99228/4

    【讨论】:

      【解决方案3】:

      我看到这里已经有答案了,但这是我的看法,看起来相似的我的可能效率较低,但越多越好 :)

       Declare @t table (Name nvarchar(80)) 
      Insert into @t values  
       ('ABC:CE')
       ,('ABC:LI')    
       ,('ABC:XP')    
       ,('ABD:CE')    
       ,('ABD:LI')    
       ,('ABE:LI')    
       ,('ABE:XP')    
       ,('ABF:XP')
      
      Declare @c table (Cat nvarchar(2)) 
      Insert into @c values  
       ('CE')
       ,('LI')  
       ,('XP')
      
      
      SELECT 
          possible.prefix
          ,possible.Cat
          ,possible.prefix + ':' + possible.Cat
          --,selector.Prefix
          --,selector.suffix
      
      FROM
      (
      select  
          SUBSTRING(Name,1,charindex(':',Name)-1) as prefix
          ,SUBSTRING(Name,charindex(':',Name)+1,2) as suffix
      from @t
      
      ) as selector
      right Join 
      (
          SELECT DISTINCT
              SUBSTRING(Name,1,charindex(':',Name)-1) as prefix
          --  ,SUBSTRING(Name,charindex(':',Name)+1,2) as suffix
              ,Cat
          FROM @t
          cross join @c
      ) possible
      ON selector.prefix = possible.prefix
      and selector.suffix = possible.Cat
      where selector.suffix is null
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-03-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-16
        相关资源
        最近更新 更多