我有以下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 :(得分: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;
答案 1 :(得分:0)
在oracle 12c中有CROSS APPLY
和OUTER APPLY
条款:
(在this link中查找cross_outer_apply_clause
):
<强> cross_outer_apply_clause 强>
此子句允许您执行ANSI CROSS JOIN或的变体 ANSI LEFT OUTER JOIN 左侧关联支持。你可以指定 APPLY右侧的table_reference或collection_expression 关键词。 table_reference可以是表,内联视图或TABLE 集合表达。 collection_expression可以是子查询,a 列,函数或集合构造函数。无论如何 form,它必须返回一个集合值 - 即类型为的值 嵌套表或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
并且只列出至少有1个事务的客户端。 />
两个查询都使用右侧的相关子查询,这些子查询使用引用左侧表格的where t.client_id = c.client_id
条件。