将常规的选择语句变成相关的子查询



我有以下SQL查询:

 SELECT name, transaction_id, MIN(transaction_date)
 FROM clients
 JOIN transactions ON clients.client_id = transactions.client_id
 GROUP BY name, transaction_id;

我想将与以下结构相关联的子查询

 SELECT a, b, MIN(c)
 FROM t1
 JOIN t2 ON t1.d = t2.d
 WHERE c IN
      (SELECT * 
      FROM t2
      HAVING....)

其中 a, b, c是列名称,而 t1, t2是表。

但是我在此过程中遇到困难。

供参考,原始问题是要求返回每个客户的最早的Transaction_date及其相应的Transaction_ID。

因此,如果transactions表具有以下内容:

   transaction_id    client_id      transaction_date
         1               1              02-02-17
         2               1              02-01-17
         3               2              02-03-17
         4               2              02-04-17

相关的子查询将返回:

    name       transaction_id       transaction_date
    John            2                   02-01-17
    Mary            3                   02-03-17

您的查询不会做您认为的事情。适当的查询将是:

SELECT c.name, t.transaction_id, t.transaction_date
FROM clients c JOIN
     transactions t
     ON c.client_id = t.client_id
WHERE t.transaction_date = (SELECT MIN(t2.transaction_date)
                            FROM transactions t2
                            WHERE t2.client_id = t.client_id
                           );

更典型的查询将是:

SELECT name, transaction_id, transaction_date
FROM (SELECT c.name, t.transaction_id, t.transaction_date,
             ROW_NUMBER() OVER (PARTITION BY c.client_id ORDER BY t.transaction_date) as seqnum
      FROM clients c JOIN
           transactions t
           ON c.client_id = t.client_id 
     ) ct
WHERE seqnum = 1;

在Oracle 12c中有CROSS APPLYOUTER APPLY条款:
(在此链接中查找cross_outer_apply_clause):

cross_outer_apply_clause

此条款允许您执行ANSI交叉连接的变体或 ANSI左OUT OUT JOIN ,具有左相关支持。您可以指定 apply右侧的table_reference或collection_expression 关键词。table_reference可以是表,内联视图或表格 收集表达。Collection_expression可以是子查询 列,功能或集合构造函数。不管它是什么 表格,它必须返回收集值 - 即,其类型为 嵌套表或Varray。table_reference或collection_expression 可以参考从子句到左侧定义的表的表 应用关键字。这称为左相关

这两个子句具有(左)相关支持 - 这仅意味着可以使用相关的子查询。


您的查询可能看起来像这样:

select c.*, x.*
from clients c
cross apply (
   select transaction_id, transaction_date
   from transactions t
   where t.client_id = c.client_id
   order by transaction_date desc
   fetch first row only
) x

或使用outer apply

select c.*, x.*
from clients c
outer apply (
   select transaction_id, transaction_date
   from transactions t
   where t.client_id = c.client_id
   order by transaction_date desc
   fetch first row only
) x

后一个查询就像 LEFT JOIN-它为所有客户提供了所有交易的客户端,而前者类似于INNER JOIN,并且仅列出了至少有1个交易的客户端。





这两个查询都使用右侧相关的子查询,
这些子量使用where t.client_id = c.client_id条件,引用了左侧的表。

相关内容

  • 没有找到相关文章

最新更新