如何编写SQL查询计算两表指定条件下contractDate与ApprovalDate的日期差
嘿,我来帮你搞定这个查询问题!首先先把你的两张表结构和数据整理成更清晰的表格形式:
Table1
| caseId | name | ApprovalDate | ApprovalStatus |
|---|---|---|---|
| 150150 | John | 2018-01-29 | 41 |
| 150151 | Dave | 2018-01-02 | 41 |
Table2
| contId | StatusSourceNoKeyId | Status | contractDate |
|---|---|---|---|
| 210210 | 38^ | 150150 | ^31796794 |
| 210211 | 38^ | 150150 | ^31796797 |
| 210220 | 38^ | 150151 | ^31796720 |
你的需求核心是:关联两张表时提取Table2中StatusSourceNoKeyId的中间caseId部分,筛选Status=41的记录,再计算两个日期的差值。不同数据库的字符串处理函数略有不同,我给你整理几种主流数据库的实现方式:
1. MySQL 版本
用SUBSTRING_INDEX函数拆分分隔字符串,先取前两个分隔段,再提取最后一段得到caseId:
SELECT t1.caseId, t1.name, t1.ApprovalDate, t2.contractDate, -- 计算contractDate减去ApprovalDate的天数差 DATEDIFF(t2.contractDate, t1.ApprovalDate) AS date_difference FROM Table1 t1 JOIN Table2 t2 ON t1.caseId = SUBSTRING_INDEX(SUBSTRING_INDEX(t2.StatusSourceNoKeyId, '^|^', 2), '^|^', -1) WHERE t2.Status = '41';
2. SQL Server 版本
如果你用的是SQL Server 2016及以上,可以用STRING_SPLIT(需要兼容级别≥130):
SELECT t1.caseId, t1.name, t1.ApprovalDate, t2.contractDate, -- 按天计算日期差,第一个参数是日期部分(day/month等) DATEDIFF(day, t1.ApprovalDate, t2.contractDate) AS date_difference FROM Table1 t1 JOIN Table2 t2 ON t1.caseId = (SELECT value FROM STRING_SPLIT(t2.StatusSourceNoKeyId, '^|^') WHERE ordinal = 2) WHERE t2.Status = '41';
如果是更低版本的SQL Server,用CHARINDEX定位分隔符位置来截取:
SELECT t1.caseId, t1.name, t1.ApprovalDate, t2.contractDate, DATEDIFF(day, t1.ApprovalDate, t2.contractDate) AS date_difference FROM Table1 t1 JOIN Table2 t2 ON t1.caseId = SUBSTRING( t2.StatusSourceNoKeyId, CHARINDEX('^|^', t2.StatusSourceNoKeyId) + 3, -- 跳过第一个分隔符(长度3) CHARINDEX('^|^', t2.StatusSourceNoKeyId, CHARINDEX('^|^', t2.StatusSourceNoKeyId) + 3) - (CHARINDEX('^|^', t2.StatusSourceNoKeyId) + 3) ) WHERE t2.Status = '41';
3. Oracle 版本
用REGEXP_SUBSTR正则提取第二个匹配的片段:
SELECT t1.caseId, t1.name, t1.ApprovalDate, t2.contractDate, -- Oracle中日期直接相减得到天数差 (t2.contractDate - t1.ApprovalDate) AS date_difference FROM Table1 t1 JOIN Table2 t2 ON t1.caseId = REGEXP_SUBSTR(t2.StatusSourceNoKeyId, '[^^|]+', 1, 2) WHERE t2.Status = '41';
执行结果示例
用你的测试数据运行后,会得到如下结果:
| caseId | name | ApprovalDate | contractDate | date_difference |
|---|---|---|---|---|
| 150150 | John | 2018-01-29 | 2018-02-01 | 3 |
| 150151 | Dave | 2018-01-02 | 2018-01-03 | 1 |
内容的提问来源于stack exchange,提问作者VBS
相关产品推荐
相关产品推荐

