【问题标题】:Trying to get around lack of CTE试图解决缺乏 CTE
【发布时间】:2021-01-26 00:18:53
【问题描述】:

我在过滤较长查询的结果时遇到了一些问题。

假设我们有三列,有一些样本行:

# column_1, column_2, column_3

'value 1', 'value 2', null
'value 1', 'value 2', '2'
'value 2', 'value 2', null

我想选择所有行,但不包括 column_3 为空且其 column_1、column_2 值与至少一个非空 column_3 值相关联的行。

一个痛点是我被 MySQL 5.7 困住了,这些行是由一个相当长的文本子查询产生的。如果我有 CTE,我可以做到:

WITH 
    cte1 AS (...)
SELECT *
FROM cte1 as a
WHERE
    column_3 IS NOT NULL
    OR NOT EXISTS (
        SELECT 1
        FROM cte1 as b
        WHERE
            b.column_1 = a.column_1
            AND b.column_2 = a.column_2
            AND b.column_3 IS NOT NULL
    )

鉴于我无权访问 CTE,有什么方法可以在不复制粘贴大型子查询的情况下做到这一点?

【问题讨论】:

  • 我建议你结束折磨并升级到 MySQL 8.0。
  • 我正在学习 MySQL 8 和 Postgres 13,但对于这个特殊的东西,这不是我的选择。

标签: mysql common-table-expression


【解决方案1】:

无论有没有 CTE,您都需要复制粘贴大型子查询。将是:

with a as (subquery)
select *
from a
where ...

没有甚至更短:

select *
from (subquery) as a
where ...

【讨论】:

  • 我可能不清楚。我需要过滤该子查询的结果,所以我必须做 SELECT * FROM (subquery) as a WHERE column_3 IS NOT NULL OR NOT EXISTS (subquery_based_query)。
  • 我能做什么,考虑到子查询的长度,这实在是太令人讨厌了。
  • 对我原始帖子中查询的编辑是否无效?看起来使用 CTE 阅读起来会容易得多,但听起来你是说有或没有 CTE 都没有视觉差异?
  • 啊,我明白了,您在不存在条件中再次使用相同的子查询
  • 正确,我不确定是否有更简洁的写法(如果给定 CTE)。
【解决方案2】:

如果您在 MySQL 5.x 中没有 CTE,另一种选择是使用子查询创建视图。

然后您可以在主查询中多次使用该视图。这是一个糟糕的 CTE 替代品,可能会遇到一些限制和性能问题,但仍然可以解决问题。

create view v1 as select ...;

然后,您的主要查询几乎保持不变:

SELECT *
FROM v1 as a
WHERE
    column_3 IS NOT NULL
    OR NOT EXISTS (
        SELECT 1
        FROM v1 as b
        WHERE
            b.column_1 = a.column_1
            AND b.column_2 = a.column_2
            AND b.column_3 IS NOT NULL
    )

【讨论】:

    猜你喜欢
    • 2020-03-16
    • 2014-10-08
    • 2018-03-10
    • 1970-01-01
    • 2018-11-23
    • 2020-02-17
    • 2012-11-15
    • 1970-01-01
    相关资源
    最近更新 更多