2010-09-01 5 views
1

Bien que je sache que ce n'est pas très efficace, j'ai besoin de travailler rapidement, alors j'essaie de suivre le chemin le plus facile, ou du moins je le pensais. J'essaie d'extraire les données max d'une entité et de ne prendre en compte que les lignes où USER n'est pas null, et dans le cas où aucune ligne n'a USER non définie sur null, alors je vais prendre en compte les null.Utilisation d'une expression de cas dans une clause where

la structure de l'entité est la suivante:

  • Id int,
  • ParentId int,
  • guid varchar,
  • EventOn DateTime,
  • utilisateur int (null)

Donc, la requête est la suivante:

select RS.[$Id] RangeSheet, 
     GRST.EventOn, 
     RSIS.Id [Status], 
     RSIS.Name StatusRefex  
    from RangeSheet RS 
left outer join (select RST.ParentId RangeSheet, 
         MAX(RST.EventOn) EventOn 
        from RangeSheetTime RST 
        where RST.[User] is (case RST.[User] when null then null else not null) 
       group by RST.ParentId) GRST on RS.[$Id]=GRST.RangeSheet 
left outer join RangeSheetTime RST on GRST.EventOn=RST.EventOn 
            and GRST.RangeSheet=RST.ParentId 
left outer join RangeSheetItemState RSIS on (case when RST.StartOrEnd = 1 then 1 when RST.StartOrEnd = 0 then 4 else null end) = RSIS.Id 
where RS.[$IsDeleted]=0 

Le cas que je rencontre des problèmes est celui de la vue GRST. Que pouvais-je faire pour accomplir mes exigences?

+1

Quelle est la 'WHERE' clause destinée à atteindre? 'où RST. [Utilisateur] est (cas RST. [Utilisateur] quand null alors null else non null fin)' Même si c'était une syntaxe valide il semble redondant. –

+0

De l'entité que j'ai spécifiée ci-dessus, je veux seulement utiliser Max (RST.EventOn) sur les lignes où le champ USER n'est pas nul. Mais dans le cas où toutes les lignes ont ce champ comme nul, alors je ferai Max sur chacun d'eux. C'est ce que j'essayais de faire, certainement à tort. – Hallaghan

Répondre

2

Je suis un peu déconcerté par ce que vous faites. En quittant votre description de texte cependant quelque chose comme l'aide suivante?

;WITH t AS 
    (SELECT Id  , 
       ParentId, 
       Guid , 
       EventOn , 
       USER , 
       RANK() OVER (PARTITION BY ParentId ORDER BY 
       CASE 
         WHEN USER IS NULL 
         THEN 0 
         ELSE 1 
       END DESC, EventOn DESC) Rnk 
    ) 
SELECT * 
FROM t 
WHERE Rnk=1 
+0

Nice. Très élégant. Il m'a fallu une minute ou deux pour comprendre comment cela fonctionnait, mais j'aime ça. – Bill

+0

Merci Martin, il a fait exactement ce que je voulais. Tout fonctionne bien, merci à vous. – Hallaghan

1

Je pense que vous allez devoir vous joindre à deux sous-requêtes Max différentes.

left join (
    select RST.ParentId RangeSheet, 
      MAX(RST.EventOn) EventOn 
    from RangeSheetTime RST 
    where Not RST.[User] is NULL 
    group by RST.ParentId) max1 

Cette sous-requête ne renverra pas de ligne si toutes les lignes ParentID ont des valeurs NULL dans la colonne Utilisateur.

et

left join (
select RST.ParentId RangeSheet, 
     MAX(RST.EventOn) EventOn 
from RangeSheetTime RST 
group by RST.ParentId) max2 

Maintenant, il suffit de sélectionner la valeur souhaitée.

coalesce(max1.EventOn, max2.EventOn) as EventOn 
1

Voici ma re-écriture de votre requête:

SELECT rs.[$Id] RangeSheet, 
      grst.eventon, 
      rsis.id AS [Status], 
      rsis.name AS StatusRefex  
    FROM RANGESHEET rs 
LEFT JOIN (SELECT rst.ParentId, 
        rst.EventOn, 
        RANK() OVER (PARTITION BY rst.parentid 
            ORDER BY CASE 
               WHEN rst.user IS NULL THEN 0 
               ELSE 1 
              END DESC, rst.eventon DESC) Rnk 
      FROM RANGESHEETTIME rst) grst ON grst.parentid = rs.[$Id] 
             AND grst.rnk = 1 
LEFT JOIN (SELECT rst.eventon, 
        rst.parentid, 
        CASE rst.startorend 
        WHEN 0 THEN 4 
        WHEN 1 THEN 1 
        ELSE NULL 
        END AS item_state_id 
      FROM RANGESHEETTIME rst 
      WHERE rst.startorend IN (0, 1)) x ON x.eventon = GRST.EventOn 
              AND x.parentid = GRST.RangeSheet 
LEFT JOIN RANGESHEETITEMSTATE rsis ON rsis.id = x.item_state_id