2010-05-27 7 views
1

Je cette requête:comment ajouter une colonne dans SQL Query incl. LEFT OUTER JOIN

SELECT p.ProductName, 
      dt.MaxTimeStamp, 
      p.Responsible 
    FROM Product p 
LEFT JOIN (SELECT ProductID, MAX(TimeStamp) AS MaxTimeStamp 
      FROM StateLog 
      WHERE State = 0 
     GROUP BY ProductID, State) dt ON p.ProductID = dt.ProductID 
ORDER BY p.ProductName; 

Il fonctionne comme il se doit, mais maintenant je dois SELECT « État » trop. La partie délicate est, que je veux seulement le dernier "TimeStamp" où "State" était faux. Mais maintenant j'ai aussi besoin du "State" pour le dernier "TimeStamp".

J'ai essayé ceci:

SELECT p.ProductName, dt.State, dt.MaxTimeStamp, p.Responsible 
    FROM Product p 
LEFT JOIN (SELECT ProductID, MAX(TimeStamp) AS MaxTimeStamp, State 
      FROM StateLog 
      WHERE State = 0 
     GROUP BY ProductID, State) dt ON p.ProductID =dt.ProductID 
ORDER BY p.ProductName; 

Mais il ne fonctionne pas, car il m'a donné le « Etat » pour le lastest « TimeStamp ».

Donc j'espère qu'il y a des têtes intelligentes qui peuvent m'aider. Je suppose que c'est très simple ou très difficile à résoudre.

+0

Thx pour l'éditer pour moi tvanfosson. Je vais essayer de le rendre meilleur la prochaine fois. – radbyx

+1

mais vous filtrez pour 'state = 0' donc l'état sera toujours 0 ... –

+0

@radbyx - utilisez le bouton 0101 ou les échantillons de code de retrait de 4 espaces. Vous pouvez également utiliser les guillemets '\' 'pour mettre en ligne. – tvanfosson

Répondre

1

Luttant pour déchiffrer ce que vous cherchez, mais en lisant entre les lignes, il pourrait se résumer comme:

1) Le plus récent StateLog.Timestamp où l'État est nul

2) État de la plus récente StateLog .Timestamp

Dans ce cas, la requête suivante (plutôt laide) fonctionnerait probablement. Supposons que la colonne "Statut" de votre groupe soit une erreur d'impression de "State" car elle n'est renvoyée nulle part.

SELECT 
    p.ProductName 
    , sl.State AS StateWithLatestTimeStamp 
    , MAX(CASE WHEN dt1.State = 0 THEN dt1.MaxTimeStamp ELSE NULL END) AS LatestStateZeroTimeStamp 
FROM 
    (
    SELECT 
     ProductID 
     , State 
     , MAX(TimeStamp) AS MaxTimeStamp 
    FROM 
     StateLog 
    GROUP BY 
     ProductId 
     , State 
    ) dt1 
INNER JOIN 
    StateLog sl 
ON sl.ProductID = dt1.ProductID 
INNER JOIN 
    Product p 
ON p.ProductID = sl.ProductID 
GROUP BY 
    p.ProductName 
    , sl.State 
    , sl.TimeStamp 
HAVING 
    sl.TimeStamp = MAX(dt1.MaxTimeStamp) 
+0

Thx, ça a marché sans rien changer. J'aime la façon courte et précise de décrire les objectifs, je le ferai à partir de maintenant. Votre Assumsion a raison, comme mentionné dans mon commentaire. – radbyx

0

Un excellent travail de mise en forme par tvanfosson et OMG Ponies.

Lorsque vous utilisez GROUP BY chaque colonne doit soit:
1. Avoir une fonction d'agrégation appliqué, ou
2. Apparaître dans la clause GROUP BY.

Je ne sais pas ce qu'est Status, mais je suppose que vous en avez besoin.
Alors ceci est un exemple de la façon dont votre requête devrait ressembler:

SELECT p.ProductName, dt.State, dt.MaxTimeStamp, p.Responsible 
    FROM Product p 
LEFT JOIN (SELECT ProductID, Status, 
        MAX(State) as State, MAX(TimeStamp) AS MaxTimeStamp 
      FROM StateLog 
      WHERE State = 0 
     GROUP BY ProductID, Status) dt ON p.ProductID = dt.ProductID 
ORDER BY p.ProductName; 

Mais tout cela est une folie parce que, comme mentionné dans un commentaire, vous filtrez par State = 0 donc il n'y a aucune possibilité que votre requête renverra tout autre qu'un 0 pour l'État.

+0

État et le statut est le même, désolé mon mauvais. – radbyx

0
with cte(Productid,TimeStamp,State,Status) as 
(select productid,TimeStamp,State,status, 
max(timestamp) over (partition by productid,status) as max1 
from statelog 
) 

SELECT p.ProductName, 
      dt.MaxTimeStamp, 
      p.Responsible 
    FROM Product p 
LEFT JOIN(
select productid,max(case when state=0 then TimeStamp else null end) as MaxTimeStamp, 
max(case when Timestamp=max1 then state else null end) as MaxState, 
from statelog 
group by productid,status) 
dt ON p.ProductID = dt.ProductID 
ORDER BY p.ProductName; 

Je me demande si votre logique est un peu confus .Je vois que vous regroupez par statut, mais vous n'utilisez le statut partout. Je n'ai pas pu tester cela mais si vous postez un script de création de table et un script de population de données, nous pouvons le tester rapidement.

+0

État et le statut est le même, désolé ma mauvaise. – radbyx