【问题标题】:SQL right join, force return only one value from right hand sideSQL右连接,强制从右侧只返回一个值
【发布时间】:2010-08-13 22:42:22
【问题描述】:
table 1
---
id , name

table2
---
id , activity, datefield

table1 'right join' table2 将从右表 (table2) 返回超过 1 个结果。如何使其仅从 table2 中返回具有最高日期的“1”结果

【问题讨论】:

  • 需要更多上下文:您只是对表 2 中某些标准的最大日期感兴趣,还是对表 2 中的一堆列感兴趣?
  • table1 join 与 table2, table3,table4..etc .. 我想从 table2 中获取一行,然后是整个查询,我想返回一堆列

标签: sql oracle10g


【解决方案1】:

你写的关于你的问题的信息很差,但我会试着举一个例子来帮助你。

您有一个表“A”和一个表“B”,您需要获取与表“A”相关的表“B”的“top”日期

示例表:

Table A:
 AID| NAME
----|-----
  1 |  Foo
  2 |  Bar

Table B:

BID | AID | DateField
----| ----| ----
 1  |   1 | 2000-01-01
 2  |   1 | 2000-01-02
 3  |   2 | 2000-01-01

如果你这样做 sql:

SELECT * FROM A RIGHT JOIN B ON B.ID = A.ID

您将获得所有通过 ID 关联的 A 和 B 信息(在这种理论情况下,这是两个表共同链接关系的字段)

A.AID | A.NAME | B.BID | B.AID | B.DateField
------|--------|-------|-------|--------------
  1   |   Foo  |   1   |   1   |   2000-01-01
  1   |   Foo  |   2   |   1   |   2000-01-02
  2   |   Bar  |   3   |   2   |   2000-01-01

但您只需要表 A 的每个元素的最后日期(B 的顶部日期)

接下来,如果您只需要获取最重要的日期,则需要按 B.AID 对查询进行分组并仅获取最重要的日期

SELECT 
      B.AID, First(A.NAME), MAX(B.DateField) 
FROM 
      A RIGHT JOIN B ON B.ID = A.ID 
GROUP BY 
      B.AID

而这个操作的结果是:

B.AID | A.NAME | B.DateField
------|--------|--------------
  1   |   Foo  |  2000-01-02
  2   |   Bar  |  2000-01-01

在此结果中,我删除了一些重复的字段(例如 A.AID 和 B.AID,即两个表之间的关系)或不需要的字段。

  • 提示:如果您在 sql 中有更多表,这也有效。 sql “进行”查询,然后应用分组以使用 B 将 B 的重复限制到最高日期。

【讨论】:

    【解决方案2】:

    在 table1.id 上右连接 table2 以从 table2 中选择 id, max = max(date)

    【讨论】:

    • 我的表 1 连接到除表 2 之外的许多其他表,所以我不能像你建议的那样使用查询,因为这将返回 1 个结果。请参阅我更新的问题。我希望 table2 只返回最新的“日期字段”
    【解决方案3】:

    分析!

    测试数据:

    create table t1
      (id        number       primary key,
       name      varchar2(20) not null
      );
    
    create table t2
      (id        number not null, 
       activity  varchar2(20) not null,
       datefield date not null
      );
    
    insert into t1 values (1, 'foo');
    insert into t1 values (2, 'bar');
    insert into t1 values (3, 'baz');
    
    insert into t2 values (1, 'foo activity 1', date '2009-01-01');
    insert into t2 values (2, 'bar activity 1', date '2009-01-01');
    insert into t2 values (2, 'bar activity 2', date '2010-01-01');
    

    查询:

    select id, name, activity, datefield
      from (select t1.id, t1.name, t2.id as t2_id, t2.activity, t2.datefield,
                   max(datefield) over (partition by t1.id) as max_datefield
              from t1
                   left join t2 
                     on t1.id = t2.id
           )
     where ( (t2_id is null) or (datefield = maxdatefield) )
    

    外部 where 子句将过滤掉 t2 元组中除最大日期之外的所有日期,但保留在 t2 中没有匹配行的空行中。

    结果:

            ID NAME                ACTIVITY                 DATEFIELD
    ---------- -------- -------------------       -------------------
             1 foo           foo activity 1       2009-01-01 00:00:00
             2 bar           bar activity 2       2010-01-01 00:00:00
             3 baz
    

    【讨论】:

      【解决方案4】:

      要从查询中检索前 N 条记录,您可以使用以下语法:

      SELECT *
      FROM (your ordered by datefield desc query with join) alias_name
      WHERE rownum <= 1
      ORDER BY rownum;
      

      PS:我不熟悉 PL/SQL,所以也许我错了

      【讨论】:

      • 不,这不是我想要的。正如我所提到的,我仍然希望最终返回超过 1 个结果,我还加入了 table2 旁边的许多其他表。但是当“与 table2 正确连接”时,这部分我想返回 1 条最大日期记录
      【解决方案5】:

      我的解决方案是

      select from table1 right join table2 on (table1.id= table2.id and table2.datefiled= (select max(datefield) from table2 where table2.id= table1.id))

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-01-17
        • 2015-10-05
        • 2023-03-09
        • 2012-03-20
        • 2013-03-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多