【问题标题】:Using part of the select clause without rewriting it使用部分选择子句而不重写它
【发布时间】:2016-03-20 17:13:56
【问题描述】:

我正在使用 Oracle SQL Db,我正在尝试计算字典中以 X 字母开头的术语的数量。

这是我的查询:

SELECT Substr(Lower(Dict.Term),0,1) AS Initialchar,
       Count(Lower(Dict.Term))
FROM Dict
GROUP BY Substr(Lower(Dict.Term),0,1)
ORDER BY Substr(Lower(Dict.Term),0,1);

此查询按预期工作,但我不太满意的是我必须重写 GROUP BY 中的长“Substr(Lower(Dict.Term),0,1)”和 ORDER BY 子句。有什么办法可以重用我在 SELECT 部分中定义的那个?

谢谢

【问题讨论】:

    标签: sql oracle11g


    【解决方案1】:

    您可以使用子查询。因为 Oracle 遵循 SQL 标准,substr() 从 1 开始计数。虽然 Oracle 确实明确允许 0 ("If position is 0, then it is treated as 1"),但我发现它具有误导性,因为“0”和“1”指的是同一个位置。

    所以:

    select first_letter, count(*)
    from (select d.*, substr(lower(d.term), 1, 1) as first_letter
          from dict d
         ) d
    group by first_letter
    order by first_letter;
    

    【讨论】:

      【解决方案2】:

      不直接。输出列只能在ORDER BY 子句中引用,但不能以任何其他方式使用。唯一的方法是将它变成一个子选择,但它不会更清晰,并且可能会导致性能问题。

      【讨论】:

      • 可以参考order by子句中的initialChar别名。但这只是问题的一半,你不能在 group by 子句中引用它,所以它并没有真正的帮助。
      【解决方案3】:

      为此,我更喜欢subquery factoring

      with init as (
       select  substr(lower(d.term), 1, 1) as Initialchar
       from dict d)
      select Initialchar, count(*)
      from init
      group by Initialchar
      order by Initialchar;
      

      与相反的意思相反,IMO 这使查询更加清晰并定义了自然顺序;尤其是在使用更多子查询时。

      我不知道性能警告,但有一些限制,例如不能在另一个 with 子句中使用 with 子句:ORA-32034: unsupported use of WITH clause

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-30
        相关资源
        最近更新 更多