Как добавить столбец в SQL Query, в том числе. ЛЕВОЕ НАРУЖНОЕ СОЕДИНЕНИЕ - PullRequest
1 голос
/ 27 мая 2010

У меня есть этот запрос:

   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;

Это работает, как и должно, но теперь мне нужно ВЫБРАТЬ "State" тоже.

Самое сложное в том, что я хочу только самую последнюю "метку времени", где "State" было ложным. Но теперь мне также нужно «State» для самой последней «TimeStamp».

Я пробовал это:

   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;

Но это не сработало, потому что дало мне «State» для самой последней «TimeStamp».

Так что я надеюсь, что есть некоторые умные головы, которые могут мне помочь. Я предполагаю, что это либо очень просто, либо очень сложно решить.

Ответы [ 3 ]

1 голос
/ 27 мая 2010

Изо всех сил пытаясь расшифровать то, что вы ищете, но читая между строк, можно было бы представить в виде

1) Самая последняя StateLog.Timestamp, где State равно нулю

2) Состояние последней StateLog.Timestamp

В этом случае следующий (довольно уродливый) запрос, вероятно, будет работать. Предполагается, что столбец «Статус» в вашей группе был опечаткой «Состояние», поскольку он нигде не возвращался.

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 голосов
/ 27 мая 2010
 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;

Мне интересно, немного ли запутана ваша логика. Я вижу, что вы группируете по статусу, но вы нигде не используете статус. Я не смог проверить это, но если вы опубликуете скрипт создания таблицы и скрипт заполнения данных, мы сможем проверить это быстро.

0 голосов
/ 27 мая 2010

Отличная работа по форматированию tvanfosson и OMG Ponies.

При использовании GROUP BY каждый столбец должен:
1. Примените к нему агрегатную функцию или
2. Появляются в предложении GROUP BY.

Я не знаю, что такое Status, но я полагаю, вам это нужно.
Вот пример того, как должен выглядеть ваш запрос:

   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;

Но все это глупо, потому что, как упоминалось в комментарии, вы фильтруете по State = 0, поэтому нет никакой возможности, что ваш запрос вернет что-либо, кроме 0 для State.

...