【问题标题】:How to check if a list have any different value如何检查列表是否有任何不同的值
【发布时间】:2010-08-12 18:13:15
【问题描述】:

我有一张如下表:

(date1, date2, date3, date4, date5)

我想检查这些日期是否与其他日期不同。 简单的解决方案是:

WHERE date1 <> date2
   OR date1 <> date3
   OR date1 <> date4
   OR date1 <> date5
   OR date2 <> date3
   OR date2 <> date4
   OR date2 <> date5
   OR date3 <> date4
   OR date3 <> date5
   OR date4 <> date5

任何重要的解决方案?

【问题讨论】:

  • 所以每行有 5 个日期?而您只关心行中的每个日期都是唯一的吗?

标签: sql sql-server tsql operators logic


【解决方案1】:

顺便说一句,你的琐碎案例真的可以简化为

WHERE date1 <> date2
   OR date1 <> date3
   OR date1 <> date4
   OR date1 <> date5

使用DeMorgan's Law,这个是一样的

WHERE NOT(date1 = date2
      AND date1 = date3
      AND date1 = date4
      AND date1 = date5)

然后通过equality relationtransitive property,我们会知道如果 date1 等于其他 4 个值,那么所有 5 个彼此相等。

【讨论】:

  • 我刚刚给出了相同的答案,但你打败了我...... :) 我同意这是解决问题的最简单方法。
  • +1 很高兴看到应用了一些逻辑而不是人为的聚合
  • 等式的传递属性昨天刚刚逃脱了我......但是,这个解决方案仍然是 O(n)。我有一个超过 39 列的系统,这些列可能相等也可能不相等。这只是一个简化的例子。
  • 这是否可以保护我们免受 date2 等于 date3 的影响?
  • @automatic:是的,一旦我们知道 date1 等于我们知道的所有其他 4 个日期(通过传递属性) date2=date3、date4=date5 等。
【解决方案2】:

如果表有主键,我想这不是微不足道的。

select key, "There are duplicates"
from
(
    select key,date1 from table
    union all
    select key,date2 from table
    union all
    select key,date3 from table
    union all
    select key,date4 from table
    union all
    select key,date5 from table
) as aa
group by
  key, date1
having 
  count(*) > 1

【讨论】:

    【解决方案3】:

    按每个值分组,将按计数分组与原始计数进行比较

    【讨论】:

      【解决方案4】:

      如果您使用的是 SQL Server 2005+,您可以执行以下操作:

      With Dates As
          (
          Select PK, 'Date1' As DateType, Date1 As [Date] From Table
          Union All Select PK, 'Date2', Date2 From Table
          Union All Select PK, 'Date3', Date3 From Table
          Union All Select PK, 'Date4', Date4 From Table
          Union All Select PK, 'Date5', Date5 From Table
          )
      Select D.PK, D.DateType, D.[Date]
      From Dates As D
      Where Exists    (
                      Select 1
                      From Dates As D1
                      Where D1.PK = D.PK
                          And D1.[Date] <> D.[Date]
                      )
      

      【讨论】:

        【解决方案5】:

        这对我来说更容易用一个例子来描绘。这可行,但我不确定我是否过于复杂。

        CREATE TABLE #Dates( ID int, date1 datetime, date2 datetime, date3 datetime, date4 datetime )
        INSERT INTO #Dates VALUES( 1, '1 Jan 2008', '2 Feb 2979', '8 Nov 1967', '31 Dec 2001' ) 
        INSERT INTO #Dates VALUES( 2, '1 Jan 2008', '1 Jan 2008', '1 Jan 2008', '1 Jan 2008' ) 
        INSERT INTO #Dates VALUES( 3, '1 Jan 2008', '1 Jan 2008', '1 Jan 2008', '31 Jan 2008' ) 
        INSERT INTO #Dates VALUES( 4, '1 Jan 2008', '1 Jan 2008', '31 Jan 2008', '1 Jan 2008' ) 
        
        -- look at example data - note only row 2 has all 4 dates the same
        SELECT * FROM #Dates
        
        -- return rows where the dates are not all the same 
        SELECT ID as RowsWithDatesNotAllTheSame
        FROM 
            (
            SELECT ID, Date
            FROM 
                (
                SELECT ID, DateCol, Date
                FROM 
                    (SELECT ID, date1, date2, date3, date4 
                    FROM #Dates) p 
        
                UNPIVOT
                    ( Date FOR DateCol IN
                        (date1, date2, date3, date4)
                ) AS unpvt
                ) x
            GROUP BY ID, Date
            ) y 
        GROUP BY ID
        HAVING count(*) > 1
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-09-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多