如何以更短的方式解决这个SQL查询?

时间:2013-06-28 19:58:46

标签: sql database derby

我有2个表,Customer和Trans。

Customer
---------
c_id | cName | cSurname | cPbx | cGsm | cLastVisitDate

Trans
------
t_id | c_id | tDate | tPaymentAmount | tSaleAmount

我想选择债务大于零且自指定日期以来未进行交易的客户。

例如“列出有债务但自2012年1月20日以来未访问过的客户”

这是我试图解决的问题,但它不起作用。

select Customer.c_id, SUM (saleAmount - paymentAmount) as totalDebt, 
cLastVisitDate, 
cName, 
cSurName, 
cPbx, 
cGsm 
from Customer, Trans 
where customer.c_id = trans.c_id AND cLastVisitDate < ?

这会产生以下错误。

  

'CUSTOMER.C_ID'无效。当SELECT列表包含至少一个时   聚合然后所有条目必须是有效的聚合表达式。

我也找到了一个解决方案,它将查询与非聚合列cLastVisitDate cName cSurname cPbx cGsm分组。

 select Customer.c_id, SUM (saleAmount - paymentAmount) as totalDebt, 
    cLastVisitDate, 
    cName, 
    cSurName, 
    cPbx, 
    cGsm 
    from Customer, Trans 
    where customer.c_id = trans.c_id AND cLastVisitDate < ?
    group by customer.c_id, cLastVisitDate cName cSurname cPbx cGsm

这个解决方案有效,但它似乎并不是一种优雅的方式。有没有更优雅,更简单的方法来完成这项任务?

1 个答案:

答案 0 :(得分:1)

我建议使用连接语句。它使你的意图更清晰。我假设每个客户都有一个ID,c_id。这意味着我们可以按客户ID对交易进行分组。

SELECT c_id, SUM (tSaleAmount - tPaymentAmount) AS totalDebt
FROM Trans
GROUP BY c_id

我们现在有一个包含两列的表,即客户ID和客户的总债务。但是,您还希望包含客户信息。此信息包含在Customer表中,并包含关联客户ID。这意味着我们可以在ID上加入这两个表。

SELECT Customer.c_id, cName, cSurname, cPbx, cGsm, cLastVisitDate, totalDebt
FROM Customer
JOIN 
   (SELECT c_id, SUM (tSaleAmount - tPaymentAmount) AS totalDebt
    FROM Trans
    GROUP BY c_id) Trans
ON Customer.c_id = Trans.c_id
WHERE totalDebt > 0 AND cLastVisitDate < ?

我们通过使用名称Trans的语句命名SELECT语句返回的表。我们还添加了WHERE子句,因为我们只想返回有债务但自给定日期以来没有访问过的客户。