【问题标题】:Is there a better way to write this SQL SELECT statement than using a subquery?有没有比使用子查询更好的方法来编写这个 SQL SELECT 语句?
【发布时间】:2012-11-15 03:34:59
【问题描述】:

我有这个查询:

SELECT A, B, C
FROM (  SELECT 
        lla.id as A,
        max(decode(lla.attrid, 2, lla.valstr, null)) as B, 
        max(decode(lla.attrid, 3, lla.valstr, null)) as C
    FROM 
        llattrdata lla, 
        llattrdata lla2
    WHERE 
        lla.id = lla2.id 
    GROUP BY lla.id)
WHERE C = "Yes"

有没有更好的方法来做到这一点?我尝试使用 HAVING 子句,但无法使其对列 C="Yes" 起作用。提前致谢。

【问题讨论】:

  • 这是无效的 SQL,除非您确实有一个名为 Yes 的列。派生表(它不是子查询)没有任何处理开销,它只是语法糖,所以不用担心。

标签: sql oracle select subquery


【解决方案1】:

怎么样

SELECT 
        lla.id as A,
        max(decode(lla.attrid, 2, lla.valstr, null)) as B, 
        'Yes' as C
    FROM 
        llattrdata lla, 
        llattrdata lla2
    WHERE 
        lla.id = lla2.id 
    GROUP BY lla.id
    HAVING max(decode(lla.attrid, 3, lla.valstr, null)) = 'Yes'

您不能使用在同一查询中创建的别名。你得再写一遍

【讨论】:

  • 我喜欢“'Yes' as C”。我没想到。
【解决方案2】:

使用HAVING clause

SELECT 
    lla.id as A,
    max(decode(lla.attrid, 2, lla.valstr, null)) as B, 
    max(decode(lla.attrid, 3, lla.valstr, null)) as C
FROM 
    llattrdata lla, 
    llattrdata lla2
WHERE 
    lla.id = lla2.id 
GROUP BY lla.id
HAVING max(decode(lla.attrid, 3, lla.valstr, null)) = 'Yes'

此子句在GROUP BY 之后进行评估,用于过滤分组结果。

很遗憾,您不能在 having 子句中使用别名。在某些情况下,子查询的意图可能比 have 子句更清晰。

【讨论】:

    【解决方案3】:
    SELECT 
            lla.id as A,
            max(decode(lla.attrid, 2, lla.valstr, null)) as B, 
            max(decode(lla.attrid, 3, lla.valstr, null)) as C
        FROM 
            llattrdata lla, 
            llattrdata lla2
        WHERE 
            lla.id = lla2.id 
        GROUP BY lla.id
        HAVING max(decode(lla.attrid, 3, lla.valstr, null)) = "Yes"
    

    请阅读:Why can't I use alias in a count(*) "column" and reference it in a having clause?

    【讨论】:

      【解决方案4】:

      我会让你进入一个秘密。你所拥有的没有任何问题。所以不要满足重写它的需要。

      SELECT A, B, C
      FROM (  SELECT 
              lla.id as A,
              max(decode(lla.attrid, 2, lla.valstr, null)) as B, 
              max(decode(lla.attrid, 3, lla.valstr, null)) as C
          FROM 
              llattrdata lla, 
              llattrdata lla2
          WHERE 
              lla.id = lla2.id 
          GROUP BY lla.id)
      WHERE C = 'Yes'
      

      与以下性能相同:

      SELECT 
          lla.id as A,
          max(decode(lla.attrid, 2, lla.valstr, null)) as B, 
          max(decode(lla.attrid, 3, lla.valstr, null)) as C
      FROM 
          llattrdata lla, 
          llattrdata lla2
      WHERE 
          lla.id = lla2.id 
      GROUP BY lla.id
      HAVING max(decode(lla.attrid, 3, lla.valstr, null)) = 'Yes';
      

      在此处避免使用内联视图将不会获得任何性能。哪个对你来说更易读,就去吧。

      【讨论】:

      • 这里有几个很好的答案,但是当你继续谈论性能时,我检查了你的答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多