2012-02-19 137 views
0

我有一個表租賃:SQL GROUP BY返回空集

rentalId int(11)    
Customer_customerId  int(11)   
Vehicle_registrationNumber varchar(20)    
startDate datetime    
endDate  datetime   
pickUpLocation int(11)     
returnLocation int(11)      
booking_time timestamp     
timePickedUp timestamp    
timeReturned timestamp 

和表支付:

paymentId int(11)      
Rental_rentalId  int(11)  
amountDue decimal(10,2)     
amountPaid decimal(10,2)    
paymentDate  timestamp 

我運行兩個組的功能,第一個計算保留的數量和求和付款日期,此功能只有在pickUpLocation`省略時才按預期工作,否則返回不正確的值。 :

SELECT COUNT(rentalId) AS number_of_rentals, MONTH(booking_time) AS month, 
`YEAR(booking_time) AS year, 
CONCAT(DAY(booking_time), '-', MONTH(booking_time), '-',` 
YEAR(booking_time)) AS date, SUM(amountDue) AS total_value, SUM(amountPaid) AS 
total_paid, `pickUpLocation` 

FROM (`rental`) 
JOIN `payment` ON `payment`.`Rental_rentalId` = `rental`.`rentalId` 

GROUP BY DAY(booking_time) 

HAVING `month` = 2 
AND `year` = 2012 
AND `pickUpLocation` = 1 
ORDER BY `booking_time` desc 

LIMIT 31 

第二個功能預計將總結的保留和付款(包括到期和接收的)整個月,對於一個特定的位置:

SELECT COUNT(rentalId) AS number_of_rentals, MONTH(booking_time) AS month, 
YEAR(booking_time) AS year, SUM(amountDue) AS total_value, 
SUM(amountPaid) AS total_paid, 
`pickUpLocation` 

    FROM (`rental`) 
    JOIN `payment` ON `payment`.`Rental_rentalId` = `rental`.`rentalId` 

    GROUP BY MONTH(booking_time) 

    HAVING `month` = 2 
    AND `year` = 2012 
    AND `pickUpLocation` = 1 
    ORDER BY `booking_time` desc 

它適用於一些地方和沒有按」 t爲其他人工作(當有很多預訂時返回正確的集合,但是當只有很少的時候,它返回空集合)。我使用MySQL。任何幫助不勝感激。

回答

1

您可能需要推一些條件從HAVINGWHERE條款:

WHERE YEAR(booking_time) = 2012 
    AND MONTH(booking_time) = 2 
    AND `pickUpLocation` = 1 

GROUP BY DAY(booking_time) 

LIMIT 31 

對於一個特定的月份,你甚至都不需要GROUP BY

WHERE YEAR(booking_time) = 2012 
    AND MONTH(booking_time) = 2 
    AND `pickUpLocation` = 1 

以上條件關於性能不是很好:

WHERE YEAR(booking_time) = 2012 
    AND MONTH(booking_time) = 2 

你應該把它變成:

WHERE booking_time >= '2012-02-01' 
    AND booking_time < '2012-03-01' 

所以查詢可以booking_time使用索引(如果您有或添加一個將來),所以它不會調用YEAR()MONTH()功能表中的每一行。

+0

這就解決了它,非常感謝代碼和您的性能建議! – tomsky 2012-02-21 00:42:19

3

你正在做一個rentalpayment之間的內部連接,這意味着你只會得到已支付的租金。如果您想在結果中找到沒有付款信息的租金,則需要使用LEFT JOIN而不僅僅是(內部)JOIN

請注意,如果沒有付款帳戶,可能會導致結果爲NULL,因此您可能必須使用control flow functions之一來調整查詢的輸出。

編輯:你也是GROUP ing在你的條件之前,那將GROUP一個月的所有行整合成一行。由於年份和PickupLocation可能會有所不同,因此您會在這兩個字段中獲得隨機值(可用的值)。然後HAVING將過濾這些隨機字段,留下可能爲空的結果集。另一方面,WHERE將會看到每行之前的每一行,並在行到行的基礎上做正確的事情(tm),所以應該把條件放在那裏。

(同樣的變動可能應該做你的第一個,工作,查詢)

演示here

+0

我把這個JOIN改成了LEFT JOIN,但它仍然是一樣的。 amountDue和amountPaid字段中沒有NULL,默認值爲0.00,但仍返回空集。例如,第一個函數返回: (日期)16-2-2012 \t(保留)1 \t(到期金額)31.00 \t(已付金額)10.00英鎊,而第二個參數(年,月,分支)返回空集。 – tomsky 2012-02-19 23:22:40

+1

@tomsky我收到您所查詢的相同數據的回覆, http://sqlfiddle.com/#!2/9f78c/4 – 2012-02-19 23:46:19

+1

謝謝,但由於某種原因,它不適用於我的數據:http://sqlfiddle.com/#!2/99294/1 – tomsky 2012-02-20 00:10:21