SELECT a.*, b.predict_day FROM dw.ol_autotask_model_channels_predict_content a JOIN ( SELECT cust_id, dt, SUM(CASE WHEN predict IN ('other', 'middle') THEN 0 ELSE 1 END) AS predict_day FROM dw.ol_autotask_model_channels_predict_content WHERE dt BETWEEN '20230601' AND '20230630' GROUP BY cust_id, dt ) b ON a.cust_id = b.cust_id AND a.dt = b.dt WHERE b.predict_day = 0 and a.dt BETWEEN '20230601' AND '20230630' ;
时间: 2024-04-08 12:28:28 浏览: 95
你的查询看起来是正确的,但是在这种情况下,你可以进一步简化查询语句。以下是优化后的查询代码:
```sql
SELECT a.*, b.predict_day
FROM dw.ol_autotask_model_channels_predict_content a
JOIN (
SELECT cust_id, dt, COUNT(*) AS predict_day
FROM dw.ol_autotask_model_channels_predict_content
WHERE dt BETWEEN '20230601' AND '20230630' AND predict NOT IN ('other', 'middle')
GROUP BY cust_id, dt
HAVING COUNT(*) = 0
) b ON a.cust_id = b.cust_id AND a.dt = b.dt
WHERE a.dt BETWEEN '20230601' AND '20230630';
```
在上述查询中,我们使用了一个内部子查询来计算 `predict_day`,并通过 `HAVING COUNT(*) = 0` 条件筛选出 `predict_day` 为 0 的记录。同时,我们将 `predict NOT IN ('other', 'middle')` 条件移至子查询中,以进一步简化查询。
请注意,上述优化仅是基于你提供的查询进行的。根据实际数据量和索引情况,可能还有其他优化方法可供考虑,例如添加适当的索引或分区策略。
相关问题
优化select a.*, b.predict_day from dw.ol_autotask_model_channels_predict_content a join (select cust_id, sum(case when predict in ('other', 'middle') then 0 else 1 end) predict_day, dt from dw.ol_autotask_model_channels_predict_content where dt BETWEEN '20230601' AND '20230630' group by cust_id, dt ) b on a.cust_id = b.cust_id and a.dt = b.dt where b.predict_day = 0 and a.dt BETWEEN '20230601' AND '20230630'
你可以尝试对查询进行以下优化:
1. 使用表别名简化查询语句,并提高可读性。
2. 将 `WHERE` 子句中的日期范围条件移至子查询中,以减少不必要的数据读取。
3. 使用连接条件 `a.dt = b.dt` 替代 `a.dt BETWEEN '20230601' AND '20230630'`,以提高查询的准确性和性能。
以下是优化后的查询代码:
```sql
SELECT a.*, b.predict_day
FROM dw.ol_autotask_model_channels_predict_content a
JOIN (
SELECT cust_id, SUM(CASE WHEN predict IN ('other', 'middle') THEN 0 ELSE 1 END) AS predict_day, dt
FROM dw.ol_autotask_model_channels_predict_content
WHERE dt BETWEEN '20230601' AND '20230630'
GROUP BY cust_id, dt
) b ON a.cust_id = b.cust_id AND a.dt = b.dt
WHERE b.predict_day = 0;
```
请注意,上述优化仅是基于你提供的查询进行的。根据实际数据量和索引情况,可能还有其他优化方法可供考虑,例如添加适当的索引或分区策略。
优化代码select a.*,b.predict_day from dw.ol_autotask_model_channels_predict_content a left join ( select cust_id, sum(case when predict in ('other', 'middle') then 0 else 1 end) predict_day, dt from dw.ol_autotask_model_channels_predict_content where dt = '20230601' group by cust_id, dt ) b on a.cust_id = b.cust_id and a.dt = b.dt where a.dt='20230601' and b.predict_day = 0 limit 50
你的查询代码已经很不错了,不过仍然可以进行一些优化。以下是对你的查询进行优化的建议:
1. 使用内连接代替左连接:根据查询条件,你只关心预测天数为0的记录。因此,可以将左连接改为内连接,这样可以减少JOIN的数据量。
2. 将子查询的结果作为临时表:将子查询的结果作为一个临时表,并使用该临时表进行JOIN操作,可以提高查询效率。
3. 移除无用的条件:由于子查询已经限定了日期(dt = '20230601'),在主查询中再次限定日期是多余的,可以移除这个条件。
优化后的查询代码如下:
```sql
WITH temp_table AS (
SELECT cust_id, sum(CASE WHEN predict IN ('other', 'middle') THEN 0 ELSE 1 END) AS predict_day
FROM dw.ol_autotask_model_channels_predict_content
WHERE dt = '20230601'
GROUP BY cust_id
)
SELECT a.*, b.predict_day
FROM dw.ol_autotask_model_channels_predict_content a
JOIN temp_table b ON a.cust_id = b.cust_id
WHERE a.dt = '20230601'
AND b.predict_day = 0
LIMIT 50;
```
通过使用临时表和内连接,可以提高查询效率。请根据需要进行适当调整,并确保表名、列名和约束条件与你的实际情况相匹配。
阅读全文