如何在SQL查询中添加包含的列。 LEFT OUTER JOIN

时间:2010-05-27 00:24:35

标签: join left-join sql

我有这个查询:

   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;

它的工作原理应该如此,但现在我也需要选择“状态”。

棘手的部分是,我只想要最新的“TimeStamp”,其中“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;

但它没有用,因为它给了我最新“TimeStamp”的“状态”。

所以我希望有一些聪明的人可以帮助我。我猜这要么很简单,要么很难解决。

3 个答案:

答案 0 :(得分:1)

努力破译你正在寻找的东西但是在这些线之间阅读可以概括为:

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)

答案 1 :(得分:0)

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以外的任何内容。

答案 2 :(得分: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;

我想知道你的逻辑是否有点混淆。我看到你按状态分组,但你不在任何地方使用状态。 我无法测试它,但如果您发布表创建脚本和数据填充脚本,我们可以快速测试它。