2013-06-28 62 views
1

我有2個表格,Customer和Trans。如何以更短的方式解決這個SQL查詢?

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

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

我想選擇債務大於零且自指定日期以來未進行交易的客戶。

例如「名單誰擁有的債務,自20.01.2012沒有訪問過的客戶」

這是我試圖解決,但它不工作。

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 

此解決方案的作品,但它似乎沒有優雅的方式做it.Is有沒有更優雅,更簡單的方式做這個任務?

+0

這有什麼不好看的。我無法想象一個相當可讀的等價查詢。 – Pete

+0

使用所有非聚合列進行分組看起來並不是最好的方式。 – user1906555

+0

我想你還需要由customer.c_id字段進行分組。據我所知,查詢中出現的所有非聚合列需要按照它們分組,這是執行它的通常方式。簡化分組代碼(但在另一部分中使其複雜化)的一種方法是將聚合函數封裝在子查詢中。然後,您可以將聚合函數的結果用作新列。 – Miquel

回答

1

我會建議使用連接語句。它使你的意圖更清晰。我假設每個客戶都有一個ID,c_id。這意味着我們可以按客戶ID對交易進行分組。

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

我們現在有一張有兩列的表格,即客戶ID和客戶的總債務。但是,您也想包含客戶信息。該信息包含在客戶表中,並帶有一個關聯客戶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子句中添加,因爲我們只想返回有債務且自給定日期以來未訪問過的客戶。