代码之家  ›  专栏  ›  技术社区  ›  Haoest

SQL-在Group By中使用别名

  •  125
  • Haoest  · 技术社区  · 14 年前

    SELECT 
     itemName as ItemName,
     substring(itemName, 1,1) as FirstLetter,
     Count(itemName)
    FROM table1
    GROUP BY itemName, FirstLetter
    

    这是不正确的,因为

    GROUP BY itemName, FirstLetter 
    

    GROUP BY itemName, substring(itemName, 1,1)
    

    但是为什么我们不能简单地用前者来方便呢?

    9 回复  |  直到 14 年前
        1
  •  320
  •   Codo    9 年前

    SQL的实现就像查询按以下顺序执行一样:

    1. WHERE子句
    2. GROUP BY子句
    3. HAVING子句

    对于大多数关系数据库系统,此顺序解释了哪些名称(列或别名)是有效的,因为它们必须在上一步中引入。

    因此,在Oracle和SQL Server中,不能在SELECT子句中定义的GROUP BY子句中使用术语,因为GROUP BY在SELECT子句之前执行。

    但也有例外:MySQL和Postgres似乎有额外的智能性来支持它。

        2
  •  29
  •   Chris Shaffer    14 年前

    您可以始终使用子查询,这样就可以使用别名;当然,请检查性能(db服务器可能会运行相同的子查询,但不会影响验证):

    SELECT ItemName, FirstLetter, COUNT(ItemName)
    FROM (
        SELECT ItemName, SUBSTRING(ItemName, 1, 1) AS FirstLetter
        FROM table1
        ) ItemNames
    GROUP BY ItemName, FirstLetter
    
        3
  •  18
  •   Bill Gribble    14 年前

    至少在PostgreSQL中,您可以在groupby子句中使用resultset中的列号:

    SELECT 
     itemName as ItemName,
     substring(itemName, 1,1) as FirstLetter,
     Count(itemName)
    FROM table1
    GROUP BY 1, 2
    

    当然,如果您以交互方式执行此操作,并且编辑查询以更改结果中列的数量或顺序,那么这将是一个难题。但仍然如此。

        4
  •  15
  •   bobs    14 年前

    由于处理的逻辑顺序,SQL Server不允许您引用GROUP BY子句中的别名。GROUPBY子句是在SELECT子句之前处理的,因此在计算GROUPBY子句时,别名是未知的。这也解释了为什么可以在ORDERBY子句中使用别名。

    SQL Server logical processing phases .

        5
  •  10
  •   Ricardo C. zero    8 年前

    我没有回答为什么会这样,只是想通过使用 CROSS APPLY GROUP BY 条款,例如:

    SELECT 
     itemName as ItemName,
     FirstLetter,
     Count(itemName)
    FROM table1
    CROSS APPLY (SELECT substring(itemName, 1,1) as FirstLetter) Alias
    GROUP BY itemName, FirstLetter
    
        6
  •  5
  •   Shannon S    9 年前

    -- Working example in postgres
    select col1 as col1_1, avg(col3) as col2_1
    from
        (select gender as col1, maritalstatus as col2, 
        yearlyincome as col3 from customer) as layer_1
    group by col1_1;
    
    -- Failing example in postgres
    select col2 as col1, avg(col3)
    from
        (select gender as col1, maritalstatus as col2,
        yearlyincome as col3 from customer) as layer_1
    group by col1;
    
        7
  •  4
  •   Community CDub    8 年前

    有些DBMS允许您使用别名,而不必重复整个表达式。
    Teradata就是这样一个例子。

    this SO question

    简单而健壮的替代方法是始终重复groupby子句中的表达式。
    DRY不适用于SQL。

        8
  •  1
  •   GGGforce    10 年前

    在SQLite中对视图中的结果进行分组时,请注意使用别名。如果别名与任何基础表(视图)的列名相同,则会得到意外的结果

        9
  •  0
  •   Bob Jarvis - Слава Україні    14 年前

    早在那一天,我发现Rdb(Oracle现在支持的以前的DEC产品)允许在GROUPBY中使用列别名。主流Oracle版本11不允许在GROUP BY中使用列别名。不确定Postgresql、SQL Server、MySQL等是否允许。基督教青年会。

        10
  •  0
  •   rogerdpack    4 年前

    选择 itemName作为ItemName1, 子字符串(itemName,1,1)作为第一个字母, 从表1 按ItemName1,FirstLetter分组;