在某些情况下,选择出现一次以上的记录

时间:2018-06-20 07:10:36

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

我的表有三列:

  • 第一列代表国名的两个字母快捷键(AF代表阿富汗,AL代表阿尔巴尼亚等)
  • 第二列是日期
  • 第三列只能包含值01

在第一列中,可以有一个以上的国家/地区,并且它们总是用逗号分隔,后跟空格。

如果一个国家同时出现在两个列表中,则我的工作是发出警告(更准确地说,如果一个国家在同一日期的第三列中的值是0和值1, )。

我该怎么办?

下表代表我应该发出警告的情况(由于AF):

+-----------------+-------------+------------+
|  Country list   |    Date     | True/False |
+-----------------+-------------+------------+
| AF, AL, DE, MA  | 20.06.2018. |          1 |
| LC, KN, AF      | 20.06.2018. |          0 |
+-----------------+-------------+------------+

2 个答案:

答案 0 :(得分:0)

定义拆分功能,例如,使用此功能(更多信息here):

group by

现在,您可以分割国家/地区列表和国家代码上的22.06.2018.,以查找出现多次的代码(我添加了另一个日期declare @tmp table([CountryList] varchar(max), [Date] varchar(20), TrueFalse bit) insert into @tmp values ('AF, AL, DE, MA','20.06.2018.', 1), ('LC, KN, AF','20.06.2018.', 0), ('AF, AL, DE, MA','22.06.2018.', 1), ('LC, KN, AF','22.06.2018.', 0) SELECT [Date], value as country, count(distinct [TrueFalse]) FROM @tmp CROSS APPLY STRING_SPLIT(replace([CountryList],', ','|'), '|') group by value, [Date] 来获得更完整的示例):

SELECT  [Date], value as country, count(distinct [TrueFalse])
FROM @tmp   
    CROSS APPLY STRING_SPLIT(replace([CountryList],', ','|'), '|')
        group by value, [Date]
        having count(distinct [TrueFalse]) > 1

结果:

enter image description here

现在,您可以过滤结果以找出多个代码:

STRING_SPLIT

结果:

enter image description here

在SQL Server 2016+中,您可以使用新的SELECT [Date], splitdata as country, count(distinct [TrueFalse]) FROM @tmp CROSS APPLY [dbo].[fnSplitString](replace([CountryList],', ','|'), '|') group by splitdata, [Date] having count(distinct [TrueFalse]) > 1 函数,而无需使用自定义拆分函数:

{{1}}

答案 1 :(得分:0)

如果您无法创建函数,请尝试以下操作:

WITH tTable --Your table
AS (SELECT [CountryList], [Date], TrueFalse
      FROM ( VALUES ('AF, AL, DE, MA', '2018-20-06', 1)
                  , ('LC, KN, AF'    , '2018-20-06', 0)
                  , ('AF, AL, DE, MA', '2018-21-06', 1)
                  , ('LC, KN, AF'    , '2018-21-06', 0)
           ) tTable([CountryList], [Date], TrueFalse)
   )
, tTableRecursive 
    AS( SELECT nCharIndex  = CHARINDEX(',', [CountryList]) -- Find Comma
                           -- Find first country
             , Country     = CASE WHEN CHARINDEX(',', [CountryList]) = 0 
                                  THEN [CountryList]
                                  ELSE SUBSTRING ([CountryList], 0, CHARINDEX(',', [CountryList]))

                             END
                             --List without first country
             , CountryList = CASE WHEN CHARINDEX(',', [CountryList]) = 0 
                                  THEN ''
                                  ELSE SUBSTRING ([CountryList], CHARINDEX(',', [CountryList])   + 1   , 500)
                             END
             , [Date]
             , TrueFalse
          FROM tTable tTable

         UNION ALL

        SELECT nCharIndex  = CHARINDEX(',', CountryList, 0)
                           -- Recursive Get Next Country
             , Country     = CASE WHEN CHARINDEX(',', CountryList, 0) = 0 
                                  THEN CountryList
                                  ELSE SUBSTRING (CountryList, 0, CHARINDEX(',', CountryList))
                             END
                             -- Remove country of list
             , CountryList = CASE WHEN CHARINDEX(',', CountryList, 0) > 0 
                                  THEN SUBSTRING (CountryList   , CHARINDEX(',', CountryList)    + 1 , 500)
                                  ELSE ''
                             END
             , [Date]
             , TrueFalse
          FROM tTableRecursive tTableRecursive
         WHERE tTableRecursive.nCharIndex > 0
)

, tResult 
    AS ( SELECT Country = LTRIM(Country)
              , [Date]            
           FROM tTableRecursive    
          GROUP BY LTRIM(Country) 
               , [Date]     
          HAVING COUNT(DISTINCT TrueFalse) > 1
       )

SELECT Country 
     , [Date]
  FROM tResult
相关问题