SQL如何关联3张表查询并判断订单日期是否在培训有效期内?
你原来的SQL存在两处明显问题:
- JOIN语法错误,INNER JOIN的ON子句后需要写表关联的匹配条件,不能直接跟表名
- 直接用
Start_date = order_date的条件只能匹配下单日刚好等于培训起始日的记录,完全不符合需求
实现逻辑
要找到无有效培训的订单,核心是用左连接匹配该销售员对应年份内有效的培训记录,匹配不到的就是目标订单:
- 先关联订单表和销售员表,关联键为销售员ID(如果不需要取销售员字段,也可以省略这层关联)
- 左连接培训表,关联条件为:① 销售员ID匹配 ② 订单日期的年份落在培训起始和结束日期的年份区间内
- 最后过滤出培训表无匹配数据的记录即可
不同场景SQL示例
场景1:所有日期字段为日期类型
以MySQL/SQL Server为例,直接用YEAR()函数提取年份:
SELECT t2.* -- 可按需调整返回字段,比如加上销售员姓名等 FROM Orders t2 INNER JOIN Salesperson t1 ON t1.salesperson_id = t2.salesperson_id LEFT JOIN Training t3 ON t3.salesperson_id = t2.salesperson_id AND YEAR(t2.order_date) BETWEEN YEAR(t3.start_date) AND YEAR(t3.end_date) WHERE t3.training_id IS NULL;
场景2:日期字段为字符串类型(存储格式为MM/DD/YYYY)
需要先把字符串转成日期类型再提取年份,示例为MySQL语法:
SELECT t2.* FROM Orders t2 INNER JOIN Salesperson t1 ON t1.salesperson_id = t2.salesperson_id LEFT JOIN Training t3 ON t3.salesperson_id = t2.salesperson_id AND YEAR(STR_TO_DATE(t2.order_date, '%m/%d/%Y')) BETWEEN YEAR(STR_TO_DATE(t3.start_date, '%m/%d/%Y')) AND YEAR(STR_TO_DATE(t3.end_date, '%m/%d/%Y')) WHERE t3.training_id IS NULL;
如果是Oracle数据库,把YEAR()换成EXTRACT(YEAR FROM 日期),字符串转日期用TO_DATE(日期字符串, 'MM/DD/YYYY')即可。
内容的提问来源于stack exchange,提问作者julz oh
相关产品推荐
相关产品推荐

