如何在这里选择最大值的区别

时间:2012-01-10 21:46:33

标签: sql distinct

我有以下表A&表B,其中A是B的一对多;对于A的每个记录,我需要为A的每个组选择B上相应的最大记录。 即分组是基于last_updated_time完成的。

SELECT taba.ws_name, tabb.b2a,  max(tabb.last_update_time)
FROM TabA taba, TabB tabb
where taba.name = 'xyz'
and taba.id = tabb.b2a 
group by taba.ws_name, tabb.b2a 

这很好用。

当我需要选择“状态”以及最后一次交易时出现问题,这会导致选择重复项,因为状态可能会失败或成功。

我的要求是只选择最大记录而不管其状态如何(尽管我也需要显示状态)

因此,当任何“ws_name”有多个失败记录和成功记录时,就会为两个组选择MAX updated_time(“失败”和“成功”)。

以下是我尝试过的查询,并且没有提供关于如何删除因状态而选择的重复项的线索。

SELECT taba.ws_name, tabb.b2a, **tabb.status**,  max(tabb.last_update_time)
FROM TabA taba, TabB tabb
where taba.name = 'xyz'
and taba.id = tabb.b2a 
group by taba.ws_name, tabb.b2a, **tabb.status**

3 个答案:

答案 0 :(得分:0)

通常,您需要选择最大值,然后加入此结果以获取所需的实际值。

例如:

SELECT     InnerQuery.*,
           TabB.Status

FROM      
            (SELECT     A.ws_name, 
                       B.b2a, 
                       max(B.last_update_time) AS MaxUpdatedTime

            FROM       TabA A
            INNER JOIN TabB B ON (A.id = B.b2a)

            GROUP BY   A.ws_name,
                              B.b2a) AS InnerQuery
INNER JOIN
            TabB ON (InnerQuery.b2a = TabB.b2A AND TabB.last_update_time = InnerQuery.MaxUpdatedTime)

InnerQuery为您提供了所需的所有行,但没有状态。因此,我们返回到B以获取匹配行的状态。

即。我们得到我们想要的B中的所有行,然后返回到B以获取我们唯一标识的行的状态值,因为正如您所说,引入状态只会给我们另一级别的分组。

答案 1 :(得分:0)

你需要一个嵌套的SELECT:

SELECT
    X.*, B.status
FROM
    (SELECT
        taba.ws_name,
        tabb.b2a,
        max(tabb.last_update_time) AS maxtime
     FROM
        TabA taba,
        TabB tabb
     where
        taba.name = 'xyz' and taba.id = tabb.b2a
     group by
        taba.ws_name,
        tabb.b2a) X,
    tabb B
WHERE
    X.b2a = B.b2a AND X.maxtime = B.last_update_time

我也会使用join子句。这是加入表格的“现代”方式。

SELECT
    X.*, Y.status
FROM
    ( SELECT
          A.ws_name,
          B.b2a,
          max(B.last_update_time) AS maxtime
      FROM
          TabA A
          INNER JOIN TabB B
              ON A.id = B.b2a
      WHERE
          A.name = 'xyz'
      GROUP BY
          A.ws_name,
          B.b2a) X,
    INNER JOIN TabB Y
        ON X.b2a = Y.b2a AND X.maxtime = Y.last_update_time

我用“LEFT JOIN”替换“INNER JOIN”,当TabB中没有相应的记录时,你也会得到TabA记录的结果。

答案 2 :(得分:0)

你可以使用CTE,事实上对于这种情况使用这个和子查询是相同的结果,但不同的是(在我看来)这个代码更容易阅读。

第一个块(WITH)执行查询以获取最大值及其相应的id,并将结果存储在“临时表”中。

然后在第二个查询中使用CTE查询结果中获得的最大值(第一个),并使用它们来限制原始查询的结果。

WITH TabB_CTE(b2a, last_update_time) as
(
    Select
        b2a, max(last_update_time) As last_update_time
    From
        TabB
    Group By b2a
)

SELECT 
    taba.ws_name, tabb.b2a, tabb.status, tabb.last_update_time
FROM
    TabA taba Join TabB tabb
        On  taba.id = tabb.b2a
    Join TabB_CTE tabc
        On  tabc.b2a = tabb.b2a
        And tabc.last_update_time = tabb.last_update_time
where taba.name = 'xyz'