【问题标题】:sql query to get max date from multiple columns of multiple table in db2sql查询从db2中多个表的多个列中获取最大日期
【发布时间】:2022-01-06 06:30:19
【问题描述】:

我有多个具有 date_modified 列的表,我需要使用所有这些表创建一个视图,但 date_modified 应该是这些表中 date_modified 的最大值。

    table1 
    id vendor_number fiscal_year date_created date_modified
    1    124           2021        2021/11/01   2021/11/02
    2    231           2021        2021/11/01   2021/11/03 
    3    232           2021        2021/11/02   NULL
    4    234           2021        2021/11/02   NULL
    
    table2 
    id fiscal_year discount_amt date_created date_modified
    1  2021          10.30      2021/11/01   2021/11/03
    2  2021          15.23      2021/11/01   2021/11/02
    3  2021          17.45      2021/11/02   2021/11/02
    4  2021          18.49      2021/11/02   NULL
    
    table3
    id vendor_number date_created date_modified
    1  124           2021/11/01   2021/11/04
    2  231           2021/11/01   2021/11/01
    3  232           2021/11/01   2021/11/03
    4  234           2021/11/02   2021/11/03

    Required Output :
    
    id|fiscal_year|discount_amt|vendor_number|date_created|date_modified
    1 | 2021      |  10.30     | 124         | 2021/11/01 | 2021/11/04
    2 | 2021      |  15.23     | 231         | 2021/11/01 | 2021/11/03
    3 | 2021      |  17.45     | 232         | 2021/11/02 | 2021/11/03
    4 | 2021      |  18.49     | 234         | 2021/11/02 | 2021/11/03

查看 SQL:

CREATE VIEW view_data
AS
  SELECT T1.id, T1.fiscal_year, T2.discount_amt, T3.vendor_number, T1.date_created, max(multiple date_modified columns..from multiple tables..)
    FROM   table1 AS T1
             LEFT JOIN table2 AS T2
                    ON T1.id = T2.id
             LEFT JOIN T3 v
                    ON T1.vendor_number = T3.vendor_number;

  

【问题讨论】:

  • date_created 的规则是什么?一个简单的select id, max (date_modified) as date_modified from (select id, date_modified from table1 union all select id, date_modified from table2 union all select id, date_modified from table3) group by id 声明有什么问题?
  • 我需要从多个表中创建一个具有最大 date_modified 的视图。我添加了一个示例视图定义并更新了表结构。 date_created 将从主表`table1`中使用。这需要在 DB2 中完成。
  • 您使用fiscal_year 列连接tabl1table2,但显示此连接的2 个输出行,而它必须是4 行,因为两个表都有2 行,每行具有相同的@ 987654329@。你能解释一下,为什么table1 的第一行连接到table2 的第一行(而不是第二行)?你没有弄乱连接列吗?
  • 是的,可能是我给出的示例不是我实际拥有的.. 我只是想实现 date_modified 列应该是所有表的所有 date_modified 列的最大值。请忽略连接或表数据,输出只是为了显示所需的结果。

标签: sql db2 db2-9.1


【解决方案1】:

假设 id 列是每个表的键,您可以加入它们(可能使用完全外连接),然后使用 GREATEST() 获取最新日期。

例如:

create view v as 
select
  coalesce(a.id, b.id, c.id) as id,
  b.fiscal_year,
  b.discount_amt,
  a.date_created,
  greatest(a.date_modified, b.date_modified, c.date_modified) as date_modified
from table1 a
full join table2 b on b.id = a.id
full join table3 c on c.id = b.id or c.id = a.id

编辑:如果您的 DB2 版本没有实现 GREATEST(),您可以将其替换为 [相当长的] CASE 子句:

  case when a.date_modified > b.date_modified then
    case when a.date_modified > c.date_modified 
         then a.date_modified else c.date_modified end
  else
    case when b.date_modified > c.date_modified 
         then b.date_modified else c.date_modified end
  end

或者,您可以自己实现该功能。这很简单。例如:

create function greatest(in a date, in b date) returns date
language sql
begin
  if a > b then return a; end if;
  return b;
end
//

db<>fiddle 1查看此自定义函数的运行示例。

编辑 #2:处理空值

空值不是值,数据库的行为是正确的。在存在未知日期的情况下,引擎无法确定哪个日期更大,并返回 UNKNOWN -- 以 null 的形式。

现在,如果您希望 null 在 C、Java、PHP 等编程语言中表现得一样,那么您可以 1) 使用大量 CASE/COALESCE 子句,或者您可以简单地将自定义函数修改为 wotk随你便。以下是修改后的自定义函数的示例:

create function mygreatest(in a date, in b date) returns date
language sql
begin
  if a is null then return b; end if;
  if b is null then return a; end if;
  if a > b then return a; end if;
  return b;
end

然后,您可以看到它的实际效果:

with data (x, y) as (
  select date '2021-07-01', date '2021-12-01' from sysibm.sysdummy1
  union all select date '2021-07-01', null from sysibm.sysdummy1
  union all select null, date '2021-12-01' from sysibm.sysdummy1
  union all select null, null from sysibm.sysdummy1
)
select mygreatest(x, y) as g from data;

结果:

G
----------
2021-12-01
2021-07-01
2021-12-01
null

请参阅db<>fiddle 2 的运行示例。

【讨论】:

  • 我使用的是 DB2 v9.1,GREATEST() 在 DB2 9.7v 中可用
  • @PoojaGupta 为 9.1 版添加了几个解决方案。
  • CASE 没有给出正确的结果,因为列具有 null 值。
  • @PoojaGupta 请更新问题并添加带有空值的示例数据行,以及预期的结果。
  • 我已经用空值更新了这个例子,我也把我的 db2 版本更新到了 10.1 版,所以现在 best() 正在工作.. 但是 date_modified 列包含空值,所以 best() 是如果任何表列值为空,也会返回空值。
猜你喜欢
  • 1970-01-01
  • 2016-04-13
  • 2020-03-02
  • 2018-10-21
  • 2020-11-29
  • 2018-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多