如何从组查询中的列中选择一个值

时间:2014-10-22 09:26:25

标签: sql oracle

我的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

现在,我想为每个pay_date选择最后一个customer_id,我会这样做。

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.name放到GROUP BY子句中,因为我认为它使我的SQL难以阅读:它误导任何阅读SQL的人认为结果可能有多个行具有相同的customer_id但不同的name

4 个答案:

答案 0 :(得分: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

答案 1 :(得分:2)

如果你真的不在乎选择哪个名字,你可以使用MIN,MAX,FIRST,LAST ......

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

答案 2 :(得分: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

答案 3 :(得分: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