我有一张看起来像这样的桌子:
优惠
id | 子_id | 交易开始 | 交易结束 | 国家_A | 国家_B |
---|---|---|---|---|---|
10 | 1 | 2024-10-21 | 2024-10-25 | 美国 | 俄罗斯 |
10 | 2 | 2024-10-21 | 2024-10-25 | 美国 | 中国 |
10 | 3 | 2024-10-21 | 2024-10-24 | 俄罗斯 | 美国 |
11 | 1 | 2024-10-21 | 2024-10-25 | 中国 | 俄罗斯 |
11 | 2 | 2024-10-21 | 2024-10-23 | 中国 | 美国 |
我需要计算每行的交易期限,但不包括两个国家/地区的周末和节假日。
为此,我有一张所有国家/地区所有日期的周末和假期表,如下所示。
假期
1 - 工作日
2 - 假期或周末
日期 | 国家 | 日类型 |
---|---|---|
2024-10-21 | 俄罗斯 | 2 |
2024-10-21 | 中国 | 1 |
2024-10-21 | 美国 | 1 |
2024-10-22 | 俄罗斯 | 1 |
2024-10-22 | 中国 | 2 |
2024-10-22 | 美国 | 1 |
2024-10-23 | 俄罗斯 | 1 |
2024-10-23 | 中国 | 1 |
2024-10-23 | 美国 | 2 |
2024-10-24 | 俄罗斯 | 2 |
2024-10-24 | 中国 | 1 |
2024-10-24 | 美国 | 2 |
我正在使用 SQL Impala 方言并尝试像这样的查询,但没有成功。此外,这种方法没有考虑重叠日期。最后,我无法在工作中使用 UDF。
SELECT id,
sub_id,
deal_start,
deal_end,
country_A,
country_B,
DATEDIFF(d.deal_end, d.deal_start) AS dirty_term,
COUNT(hA.date) AS country_A_hd,
COUNT(hB.date) AS country_B_hd,
(DATEDIFF(d.deal_end, d.deal_start) - GREATEST(COUNT(hA.date), COUNT(hA.date))
FROM deals AS d
LEFT JOIN holydays AS hA ON hA.country=d.country_A AND hA.date BETWEEN d.deal_start AND d.deal_end AND hA.day_type = 2
LEFT JOIN holydays AS hB ON hB.country=d.country_B AND hB.date BETWEEN d.deal_start AND d.deal_end AND hB.day_type = 2
GROUP BY id,
sub_id,
deal_start,
deal_end,
country_A,
country_B
理想情况下我需要得到这个结果:
id | 子_id | 交易开始 | 交易结束 | 国家_A | 国家_B | 日期差异 | 总计_AB_hd | 真实术语 |
---|---|---|---|---|---|---|---|---|
10 | 1 | 2024-10-21 | 2024-10-25 | 美国 | 俄罗斯 | 4 | 3 | 1 |
10 | 2 | 2024-10-21 | 2024-10-25 | 美国 | 中国 | 4 | 3 | 1 |
10 | 3 | 2024-10-21 | 2024-10-24 | 俄罗斯 | 美国 | 3 | 2 | 1 |
11 | 1 | 2024-10-21 | 2024-10-25 | 中国 | 俄罗斯 | 4 | 3 | 1 |
11 | 2 | 2024-10-21 | 2024-10-23 | 中国 | 美国 | 2 | 1 | 1 |
使用以下逻辑
总计_AB_hd
? | ? | ? | ? |
---|---|---|---|
2024-10-21 | 2024-10-22 | 2024-10-23 | 2024-10-24 |
2 | 2 | 1 | 2 |
国家_A
? | ? | ? | ? |
---|---|---|---|
1 | 2 | 1 | 2 |
国家_B
? | ? | ? | ? |
---|---|---|---|
2 | 1 | 1 | 2 |
请帮忙。
非常感谢您抽出时间。
在对 MySQL 设置进行一些修改之后,我想我找到了解决方案。希望您在移植到“SQL Impala 方言”设置时不会遇到太多麻烦。
要计算两个国家/地区的假期,它使用子查询,并在日期列上的假期表和自身之间进行联接。这会产生一个表格,其中特定日期的每个国家/地区都与同一日期的所有其他国家/地区相匹配。
SELECT * FROM holidays AS hA
JOIN holidays AS hB
ON hA.date = hB.date;
+------------+---------+----------+------------+---------+----------+
| date | country | day_type | date | country | day_type |
+------------+---------+----------+------------+---------+----------+
| 2024-10-21 | RUS | 2 | 2024-10-21 | RUS | 2 |
| 2024-10-21 | CHN | 1 | 2024-10-21 | RUS | 2 |
| 2024-10-21 | USA | 1 | 2024-10-21 | RUS | 2 |
| 2024-10-21 | RUS | 2 | 2024-10-21 | CHN | 1 |
| 2024-10-21 | CHN | 1 | 2024-10-21 | CHN | 1 |
| 2024-10-21 | USA | 1 | 2024-10-21 | CHN | 1 |
| 2024-10-21 | RUS | 2 | 2024-10-21 | USA | 1 |
| 2024-10-21 | CHN | 1 | 2024-10-21 | USA | 1 |
| 2024-10-21 | USA | 1 | 2024-10-21 | USA | 1 |
| 2024-10-22 | RUS | 1 | 2024-10-22 | RUS | 1 |
| 2024-10-22 | CHN | 2 | 2024-10-22 | RUS | 1 |
然后可以按 day_type 设置为 2 的国家/地区之一进行过滤。最后,对结果行进行计数。
SELECT id,
sub_id,
deal_start,
deal_end,
country_A,
country_B,
@datediff := DATEDIFF(d.deal_end, d.deal_start) AS datediff,
@total_AB_hd := (
SELECT COUNT(*)
FROM holidays AS hA
JOIN holidays AS hB
ON hA.date = hB.date
WHERE
hA.country = d.country_A AND hB.country = d.country_B AND
hA.date BETWEEN d.deal_start AND d.deal_end AND
(hA.day_type = 2 OR hB.day_type = 2)
) AS total_AB_hd,
(@datediff - @total_AB_hd) AS real_term
FROM deals AS d;
+------+--------+------------+------------+-----------+-----------+----------+-------------+-----------+
| id | sub_id | deal_start | deal_end | country_A | country_B | datediff | total_AB_hd | real_term |
+------+--------+------------+------------+-----------+-----------+----------+-------------+-----------+
| 10 | 1 | 2024-10-21 | 2024-10-25 | USA | RUS | 4 | 3 | 1 |
| 10 | 2 | 2024-10-21 | 2024-10-25 | USA | CHN | 4 | 3 | 1 |
| 10 | 3 | 2024-10-21 | 2024-10-24 | RUS | USA | 3 | 3 | 0 |
| 11 | 1 | 2024-10-21 | 2024-10-25 | CHN | RUS | 4 | 3 | 1 |
| 11 | 2 | 2024-10-21 | 2024-10-23 | CHN | USA | 2 | 2 | 0 |
+------+--------+------------+------------+-----------+-----------+----------+-------------+-----------+
(注意:我希望这些结果是您想要的结果,因为您在问题中提到的结果与我的不同。)