我有桌子出租:
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
它适用于某些位置而不适用于其他位置(当有许多预留时返回正确的设置,但是当只有少数时,它返回空集)。我使用MySQL。任何帮助非常感谢。
答案 0 :(得分:3)
您正在rental
和payment
之间进行内部联接,这意味着您只能获得已付款的租金。如果您想在结果中找到没有付款信息的租借,则需要使用LEFT JOIN
而不是仅使用(内部)JOIN
。
请注意,如果没有要付款的付款,结果可能会导致结果中出现NULL,因此您可能需要使用control flow functions之一来调整查询的输出。
编辑:您也是GROUP
在您的条件之前,GROUP
将{1}}一行中的所有行合并为一行。由于年份和PickupLocation可能会有所不同,您将获得这两个字段中的随机值(可用的值)。然后HAVING
将对这些随机字段进行过滤,为您留下可能为空的结果集。另一方面,WHERE
将在GROUP
之前看到每一行,并在行到行的基础上做正确的事情(tm),因此条件应放在那里。
(可能应该对您的第一个工作查询进行同样的更改)
演示here。
答案 1 :(得分:1)
您可能需要将某些条件从HAVING
推送到WHERE
子句:
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()
函数调用桌子的一排。