有表格(和列),如:
Clients
(clientID)Houses
(houseID)Visits
(clientID,houseID,visit_date)Contracts
(contractID,houseID,clientID,rentDate_from,rentDate_end)我编写这种SQL查询时遇到问题:
可以轻松计算每个客户的总访问次数,按clientID
列出所有访问次数+组,并为每个组选择count(*)
。
假设这是select_1,而select_2列出了所有客户的所有合同。
Select_1无法回答,因为必须仅对群组执行计数,其中包括:
在select_2中至少有一行“喜欢”行(这意味着至少有一个被访问的房屋被租用,因为它可能发生在客户访问了几个房屋,但租用了其他房屋,而不是访问过的房屋)。我的想法是将select_1和select_2与:
进行比较其中s1.clientID = s2.clientID和s1.houseID = s2.houseID
每个组必须包含所有行(访问次数),其日期为当天或早于合同日期
也许:datediff(day, s1.visit_date, s2.rentDate_from) >= 0
(为什么按下回车后这个论坛上有一个空行?)
答案 0 :(得分:0)
HAVING
子句用于从聚合查询中过滤组。它类似于WHERE
子句,但适用于聚合结果。在这种特殊情况下,事实证明您希望使用基本相同的查询来形成初始结果行并过滤组;对于SQL Server,WITH
子句允许您执行一次该查询并重用它。因此,你可能会得到这样的结论:
WITH previousVisits(clientId, houseId_visited, houseId_rented) AS
SELECT Visits.clientId, Visits.houseId, Contracts.houseId
FROM Visits
JOIN Contracts ON Visits.clientId = Contracts.clientId
WHERE Visits.visit_date <= Contracts.rentDate_from
SELECT clientId, houseId_rented, COUNT(*) AS visitCount
FROM previousVisits pv1
GROUP BY clientId, houseId_rented
HAVING houseId_rented IN (
SELECT houseId_visited
FROM previousVisits pv2
WHERE
pv2.clientId = clientId
AND pv2.houseId_rented = houseId_rented
)
请注意,在同一客户租用两个不同房屋的情况下,您应该考虑这是否符合您的要求。如上所述,对于每个租来的房子,它将计算出租之前访问过的所有房屋。即使这样,如果同一个客户不止一次地租用同一个房子,也存在潜在的问题。
答案 1 :(得分:0)
我使用更简单的命令查询:
选择不同的
co.clientID,
(
select count(*) from Visits vi
where vi.clientID = co.clientID and vi.visit_date <= co.rentDate_from
)
来自Contracts co的
中的co.clientID
(
select vi.clientID from Visits vi
where vi.houseID = co.houseID and vi.clientID = co.clientID and
vi.visit_date <= co.rentDate_from
)
J.B。更改后的版本:
使用previousVisits(clientId,houseId_visited,houseId_rented)AS
- &GT;选择不同的Visits.clientId,Visits.houseId,Contracts.houseId
FROM Visits
JOIN Contracts ON Visits.clientId = Contracts.clientId
WHERE Visits.visit_date <= Contracts.rentDate_from
SELECT clientId,houseId_rented,COUNT(*)AS visitCount
FROM previousVisits pv1
GROUP BY clientId,houseId_rented
有houseId_rented IN(
SELECT houseId_visited
FROM previousVisits
WHERE
- &GT; clientId = pv.1clientId
- &GT; AND houseId_rented = pv1.houseId_rented
)