2014-10-22 87 views
0

我在我的Oracle數據庫中有2個表,customerpayment,其中customer可以有多個payment如何從組查詢中的列中選擇一個值

如果我運行下面的查詢:

SELECT customer.customer_id, customer.name, payment.pay_date 
FROM customer, payment 
WHERE customer.customer_id = payment.customer_id; 

我會得到的結果如下圖所示的例子。

customer_id | name | pay_date 
---------------------------------- 
    1001 | Mr.A | 01/10/2014 
    1001 | Mr.A | 02/10/2014 
    1001 | Mr.A | 03/10/2014 
    1001 | Mr.A | 04/10/2014 

現在,我要選擇每個customer_id最後pay_date,我會做到這一點。

SELECT customer.customer_id, customer.name, max(payment.pay_date) as last_pay_date 
FROM customer, payment 
WHERE customer.customer_id = payment.customer_id 
GROUP BY customer.customer_id, customer.name; 

使得結果變得

customer_id | name | last_pay_date 
---------------------------------- 
    1001 | Mr.A | 04/10/2014 

的問題是,我知道customer.name不明顯具有相同customer_id每一位客戶。

我想知道是否有聚合函數,說ONE(),這讓我做如下:

SELECT customer.customer_id, ONE(customer.name), max(payment.pay_date) as last_pay_date 
FROM customer, payment 
WHERE customer.customer_id = payment.customer_id 
GROUP BY customer.customer_id; 

所以,我沒有把customer.nameGROUP BY條款因爲我認爲這使得我的SQL很難閱讀:它誤導了任何人閱讀SQL,認爲結果可能有多於一行,但是具有相同的customer_id但不同的name

回答

2

您可以使用FIRST()LAST()(自Oracle版本9i起)或MIN()MAX()集合函數。

SELECT 
    customer.customer_id, 
    FIRST(customer.name), 
    max(payment.pay_date) as last_pay_date 
FROM 
    customer JOIN payment 
ON 
    customer.customer_id = payment.customer_id 
GROUP BY 
    customer.customer_id; 

但是你無法預測哪些客戶的名字彈出...

Manual

+0

我不知道爲什麼我喜歡'ORA-00904錯誤:「LAST」:無效identifier'當我使用它們。 – asinkxcoswt 2014-10-22 09:38:24

+0

@asinkxcoswt您是否使用'LAST(customer.name)'? – Barry 2014-10-22 09:50:11

+0

是的,當我使用FIRST(customer.name)時,我得到了'ORA-00904:「FIRST」:無效標識符'。 – asinkxcoswt 2014-10-22 09:53:58

2

如果你真的不關心它的名字將被選中,你可以使用MIN,MAX,FIRST ,最後...

SELECT customer.customer_id, MIN(customer.name), 
     max(payment.pay_date) as last_pay_date 
FROM customer, payment 
GROUP BY customer.customer_id; 
1

你可以嘗試這樣的事情:

with 
    stat as (
    select customer_id as customer_id, 
      max(pay_date) as last_pay_date 
     from payment 
    group by customer_id) 

select customer.customer_id, 
     customer.name, 
     stat.last_pay_date 
    from stat, 
     customer 
where customer.customer_id = stat.customer_id 
+0

我正在測試'with ...選擇',你看起來很棒,但是,也許我的系統不支持它們,它總是返回0行,即使是一個簡單的查詢,例如'with stat as(select customer_id from customer)select * from stat; ' – asinkxcoswt 2014-10-22 10:07:47

+0

@asinkxcoswt:如果RDBMS不支持'with..select',它會拋出* exception *。 Oracle確實支持該功能。嘗試調試:分別執行'stat'查詢 - 是否返回任何記錄?或者使用Sql Fiddle http://sqlfiddle.com/爲我們複製併發布您的案例。 – 2014-10-22 10:57:28

+0

對於遲到的回覆感到抱歉。我正在與一個組織的數據庫合作,這個數據庫非常龐大,背後有許多我不知道的東西,所以我認爲我無法複製它。我也認爲這是奇怪的,沒有錯誤被拋出。還有一件奇怪的事情:當我在命令窗口模式下在PL/SQL Developer中執行上面的SQL時,不是返回「沒有選擇行」,而是返回「沒有」。並且,在SQL窗口模式下,結果窗口會顯示類似於所選列的標題相互堆疊的錯誤。 – asinkxcoswt 2014-10-22 16:19:46

0

嘗試窗口函數

SELECT customer.customer_id,customer.name, max(payment.pay_date) Over(Partition by customer.name) as last_pay_date 
    FROM customer, payment 
    WHERE customer.customer_id = payment.customer_id 
相關問題