2017-03-05 37 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條件,該條件引用左側的表。