DB2 Group By但是表2重复

时间:2015-06-18 20:34:22

标签: sql group-by db2

我试图查询iSeries DB2 v6r1m0。我经常在System i Navigator中测试我的SQL语句,然后在ADO.Net中使用它们。

我已将此问题追溯至此,但我不确定如何解决此问题。

SELECT 
    a.id
    , a.otherstuff
    , MAX(a.date || ' ' || a.time) as adatetime /* I'm sure it's not this line */
    , b.id
    , b.city 
    , b.state
    , MAX(b.date || ' ' || b.time) AS bdatetime
FROM 
    table1 a

INNER JOIN
    table2 b
ON a.id = b.id

GROUP BY
   a.id, a.otherstuff, b.id, b.city, b.state

它会显示所有b.cities和b.states,即使我只想要b.city和b.state的最大值。

a.id    a.otherstuff    a.adatetime     b.id    b.city          b.state b.datetime  
a.dup1  a.dup1          a.dup1          b.dup1  San Francisco   CA      1-Jan   1:00
a.dup1  a.dup1          a.dup1          b.dup1  Sacramento      CA      1-Jan   2:00
a.dup1  a.dup1          a.dup1          b.dup1  other cities    WA      11-Jan  3:00
a.dup2  a.dup2          a.dup2          b.dup2  San Francisco   CA      11-Jan  1:00
a.dup2  a.dup2          a.dup2          b.dup2  Sacramento      CA      11-Jan  2:00
a.dup2  a.dup2          a.dup2          b.dup2  other cities    WA      11-Jan  3:00

为什么会这样?

3 个答案:

答案 0 :(得分:1)

像这样的伪代码很难,但我认为你不需要直接加入table2,而是基于table2的派生查询。

...
FROM 
    table1 a
    INNER JOIN
    (
    SELECT
        table2.*
    FROM
        (
        SELECT
            table2.id,
            MAX(table2.datetime) AS MaxDateTime
        ) DerivedMax
        LEFT OUTER JOIN
        table2 ON table2.datetime = DerivedMax.MaxDateTime AND table2.id = DerivedMax.id
    ) DerivedOnlyRowsFromTable2YouCareAbout ON a.id = DerivedOnlyRowsFromTable2YouCareAbout.id

根据table1中数据的存在方式,可能需要相同的处理方式。如果这还不够有用,我会要求你制作一个具有实际结构和数据的sqlfiddle。正如我所说,伪代码可能会留下一些需要的东西。

答案 1 :(得分:1)

使用GROUP BY,您的结果集将为列出的列中的每个唯一值组合保留一行。因此,除非所有按表1中的列选择和分组的值都保持相同的值,否则即使没有连接第二个表,最终也会有多行。

如果只想要b.city和b.state具有最大值,则需要使用WHERE条件挑出相应的行 - 如下所示@mustaccio。

一些事情

SELECT
  a.id
  , a.otherstuff
  , a.date_time
  , b.city
  , b.state
  , b.date_time
FROM
  table1 a
INNER JOIN
  table2 b
ON
  a.id = b.id
WHERE
  b.date_time = (SELECT MAX(date_time) FROM table2)
;

应该提供。

如果您想要结果中table1的最大date_time值 - 无论来自哪条记录,请尝试

SELECT
  a.id
  , a.otherstuff
  , (SELECT MAX(date_time) FROM table1) a_max_date_time
  , b.city
  , b.state
  , b.date_time b_date_time
FROM
  table1 a
INNER JOIN
  table2 b
ON
  a.id = b.id
WHERE
  b.date_time = (SELECT MAX(date_time) FROM table2)
;

查看实际操作:SQL Fiddle。 (抱歉 - SQL Fiddle中没有DB2;每个只有一个date_time列。)

如果需要进一步的细节/调整,请发表评论。 (样本数据和预期输出将特别有用......)

答案 2 :(得分:0)

你说"我只想要b.city和b.state的最大值"。

我认为这意味着你只需要在结果集中有一行 - 一行具有某些列的最高值,而没有其他任何记录。

可能只是在最后添加ORDER BYFETCH FIRST条款

SELECT 
       a.id
       , a.otherstuff
       , MAX(a.xdate || ' ' || a.xtime) as adateinfo /* I'm sure it's not this     line */
       , b.id
       , b.city 
       , b.state
       , MAX(b.xdate || ' ' || b.xtime) as bdateinfo
  FROM table1 a
  JOIN table2 b
     ON a.id = b.id
  GROUP BY
     a.id, a.otherstuff, b.id, b.city, b.state, b.bdateinfo
  ORDER BY 
     bdateinfo desc
  FETCH FIRST ROW ONLY

然而,而不是加入和分组所有这些记录,它可能很多更有效地将其缩小到table2中的单个记录,尤其是如果文件很大。

SELECT a.id 
     , a.otherstuff
     , MAX(a.xdate || ' ' || a.xtime) as adateinfo 
     , b.city 
     , b.state
     , b.bdateinfo  
  FROM table1 a
  JOIN (
         SELECT id
               ,city
               ,state
               ,xdate
               ,xtime
               ,(xdate || ' ' || xtime) AS bdateinfo
           FROM table2 i
           ORDER BY xdate DESC, xtime DESC
           FETCH FIRST ROW ONLY
       ) AS b
       ON a.id = b.id
GROUP BY
   a.id, a.otherstuff, b.city, b.state, b.bdateinfo

所以你应该得到像

这样的东西
ID   OTHERSTUFF        ADATEINFO   CITY             STATE    BDATEINFO
27   whatever stuff    1/05 3:00   San Francisco    CA       1/11 1:00

希望这是你想要的。

脚注:我从结果中删除了b.id,看似多余和无关,因为它必须等于a.id