2017-03-05 39 views
0

我有我下面的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 
+0

为什么你想把它变成一个相关的子查询? –

+0

这是原始问题的一部分要求。我想出了在常规select语句中如何做到这一点,我只是有问题把它变成相关子查询。 – 5120bee

回答

1

您的查询没有做什么,你认为它。一个适当的查询是:

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; 
+0

t2.ctransaction_date与t.transaction_date不同吗?为什么我们需要制作“秒”t2.transaction_date? – 5120bee

+0

@ 5120bee。 。 。如果你使用'row_number()',你不会。 –

+0

我还没有听说过那个功能。 'row_number()'做什么? – 5120bee

0

在甲骨文12C有CROSS APPLYOUTER APPLY条款:
(寻找cross_outer_apply_clausethis link):

cross_outer_apply_clause

本章允许您执行ANSI CROSS JOIN的变体或使用左相关支持的ANSI LEFT OUTER JOIN 。您可以在APPLY 关键字的右侧指定 table_reference或collection_expression。 table_reference可以是表格,内联视图或TABLE 集合表达式。 collection_expression可以是子查询, 列,函数或集合构造函数。不管它的 表单是什么,它都必须返回一个集合值 - 也就是一个类型为 嵌套表或varray的值。 table_reference或collection_expression 可以将FROM子句中定义的表的列引用到APPLY关键字的左边 。 这被称为左相关

两项条文具有(左)的相关性支持 - 这只是意味着相关子都可以使用。

您的查询可能是这样的:

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,并且只列出至少有一个事务的客户端。

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