2010-08-12 7 views
4

J'ai une table comme ce qui suit:Comment vérifier si une liste a une valeur différente

(date1, date2, date3, date4, date5) 

et je veux vérifier si certains de ces dates est différent de tout autre. La solution triviale est:

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 

Toutes les solutions non triviales?

+0

Donc chaque rangée contient 5 dates? et vous vous souciez seulement que chaque date est unique dans la rangée? – automatic

+0

dates? ou des dates avec des temps? – gbn

Répondre

2

a une primaire clé, je suppose que ce n'est pas trivial.

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 
0
groupe

par chaque valeur, comparez groupés par comptage du nombre initial

0

Si vous utilisez SQL Server 2005+, vous pouvez faire quelque chose comme: si la table

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

En passant, votre cas trivial peut vraiment être simplifié juste

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

En utilisant DeMorgan's Law, c'est le même que

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

puis par le transitive property du equality relation, nous saurions que si date1 est égale aux 4 autres valeurs, alors tous les 5 sont égaux les uns aux autres.

+0

Je venais juste de mettre la même réponse mais vous m'avez battu ... :) Je suis d'accord que c'est la solution la plus simple au problème. – Bomlin

+0

+ 1 Nice à voir une certaine logique appliquée plutôt qu'un agrégat artificiel – gbn

+0

+ 1 Ne suppose aucun null. –

0

Cela a été plus facile pour moi d'imaginer avec un exemple. Cela fonctionne, mais je ne suis pas sûr si je l'ai trop compliqué.

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 
Questions connexes