MySQL-SQL选择查询,其中两个表使用where,count和have

时间:2018-10-30 02:29:37

标签: mysql sql select

有两个表:clientcontract

客户端表:

client_code INT pk
status      VARCHAR

一个客户可以拥有1个或多个合同。客户端具有一个状态列,该列指定其是否具有有效合同-值是“有效”还是“无效”。合同是为具有活动状态的客户指定的。

合同表:

contract_code INT pk
client_code   INT pk
end_date      DATE

合同的结束日期。今天之前的合同结束日期是过期的合同。

需求:报告要求所有具有合同的活跃客户,但所有(而非部分)合同均已过期。一些示例数据如下所示:

客户数据:

client_code status
----------------------------------
1           active
2           inactive
3           active
4           active

合同数据:

contract_code   client_code   end_date
-------------------------------------------------------------
11              1             08-12-2018    
12              1             09-12-2018
13              1             10-12-2018
31              3             11-31-2018
32              3             10-30-2018
41              4             01-31-2019
42              4             12-31-2018

预期结果:

client_code
-------------
1

结果:该客户端(client_code = 1)拥有所有到期日期为08-12-201809-12-201810-12-2018的合同。

我需要一些帮助来编写SQL查询以获得此结果。我不确定我必须使用哪种构造-可以指出我可以尝试的构造。该数据库是MySQL 5.5。

2 个答案:

答案 0 :(得分:0)

这是您要找的吗?

select clients.client_code
from clients
join contracts
on contracts.client_code=clients.client_code
where status='active'
group by clients.client_code
having min(end_date)>curdate() 

答案 1 :(得分:0)

一种方法使用聚合。我们可以将clientcontract表联接在一起,然后按客户进行汇总,以检查对于一个活跃的客户而言,将来是否存在合同终止日期。

SELECT
    c.client_code
FROM client c
INNER JOIN contract co
    ON c.client_code = co.client_code
WHERE
    c.status = 'active'
GROUP BY
    c.client_code
HAVING
    SUM(CASE WHEN co.end_date > CURDATE() THEN 1 ELSE 0 END) = 0;

Demo

注意:我假设您的日期仅是由于特定的格式而以M-D-Y格式显示,而end_date实际上是正确的日期列。相反,如果您将日期存储为文本,那么我们可能必须致电STR_TO_DATE才能将其首先转换为日期。