SQL - 在分组依据中使用别名

发布于 2024-09-25 21:53:45 字数 379 浏览 4 评论 0原文

只是对 SQL 语法感到好奇。所以如果我有

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)

但是为什么我们不能为了方便而简单地使用前者?

Just curious about SQL syntax. So if I have

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

This would be incorrect because

GROUP BY itemName, FirstLetter 

really should be

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

But why can't we simply use the former for convenience?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

夜无邪 2024-10-02 21:53:46

请注意,在分组依据中使用别名(对于支持它的服务,例如 postgres)可能会产生意想不到的结果。例如,如果您创建内部语句中已存在的别名,则 Group By 将选择内部字段名称。

-- 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;

Caution that using alias in the Group By (for services that support it, such as postgres) can have unintended results. For example, if you create an alias that already exists in the inner statement, the Group By will chose the inner field name.

-- 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;
青衫负雪 2024-10-02 21:53:46

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

由于this SO question。

简单而可靠的替代方法是始终重复 GROUP BY 子句中的表达式。
DRY 不适用于 SQL。

Some DBMSs will let you use an alias instead of having to repeat the entire expression.
Teradata is one such example.

I avoid ordinal position notation as recommended by Bill for reasons documented in this SO question.

The easy and robust alternative is to always repeat the expression in the GROUP BY clause.
DRY does NOT apply to SQL.

胡渣熟男 2024-10-02 21:53:46

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

Beware of using aliases when grouping the results from a view in SQLite. You will get unexpected results if the alias name is the same as the column name of any underlying tables (to the views.)

相守太难 2024-10-02 21:53:46

以前我发现 Rdb(以前的 DEC 产品,现在由 Oracle 支持)允许在 GROUP BY 中使用列别名。主流 Oracle 通过版本 11 不允许在 GROUP BY 中使用列别名。不确定 Postgresql、SQL Server、MySQL 等允许或不允许什么。 YMMV。

Back in the day I found that Rdb, the former DEC product now supported by Oracle allowed the column alias to be used in the GROUP BY. Mainstream Oracle through version 11 does not allow the column alias to be used in the GROUP BY. Not sure what Postgresql, SQL Server, MySQL, etc will or won't allow. YMMV.

初与友歌 2024-10-02 21:53:46

至少在 Postgres 中,您可以在 group by 子句中使用别名:

SELECT
项目名称为项目名称1,
substring(itemName, 1,1) 作为 FirstLetter,
计数(项目名称)
从表1
GROUP BY ItemName1,FirstLetter;

我不建议将别名重命名为大小写的更改,这会导致混乱。

In at least Postgres, you can use the alias name in the group by clause:

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

I wouldn't recommend renaming an alias as a change in capitalization, that causes confusion.

皇甫轩 2024-10-02 21:53:46

使用反引号字符( ` )

这在 MySQL 中对我有用(它也可以在 HAVING 子句中使用):

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

Use backtick character ( ` )

This works for me in MySQL (it can also be used in HAVING clause):

 SELECT 
  itemName as ItemName,
  substring(itemName, 1,1) as FirstLetter,
  Count(itemName)
 FROM table1
 GROUP BY `itemName`, `FirstLetter`
逆光飞翔i 2024-10-02 21:53:46

Oracle 23c将带来这个功能。目前还不可能。

Oracle 23c will bring this feature. For now it is not possible.

甜点 2024-10-02 21:53:45

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

  1. FROM 子句
  2. WHERE 子句
  3. GROUP BY 子句
  4. HAVING 子句
  5. SELECT 子句
  6. ORDER BY 子句

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

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

但也有例外:MySQL 和 Postgres 似乎有额外的智能来允许它。

SQL is implemented as if a query was executed in the following order:

  1. FROM clause
  2. WHERE clause
  3. GROUP BY clause
  4. HAVING clause
  5. SELECT clause
  6. ORDER BY clause

For most relational database systems, this order explains which names (columns or aliases) are valid because they must have been introduced in a previous step.

So in Oracle and SQL Server, you cannot use a term in the GROUP BY clause that you define in the SELECT clause because the GROUP BY is executed before the SELECT clause.

There are exceptions though: MySQL and Postgres seem to have additional smartness that allows it.

苏别ゝ 2024-10-02 21:53:45

您始终可以使用子查询,以便可以使用别名;当然,检查性能(数据库服务器可能会以相同的方式运行,但验证不会有什么坏处):

SELECT ItemName, FirstLetter, COUNT(ItemName)
FROM (
    SELECT ItemName, SUBSTRING(ItemName, 1, 1) AS FirstLetter
    FROM table1
    ) ItemNames
GROUP BY ItemName, FirstLetter

You could always use a subquery so you can use the alias; Of course, check the performance (Possible the db server will run both the same, but never hurts to verify):

SELECT ItemName, FirstLetter, COUNT(ItemName)
FROM (
    SELECT ItemName, SUBSTRING(ItemName, 1, 1) AS FirstLetter
    FROM table1
    ) ItemNames
GROUP BY ItemName, FirstLetter
甜心小果奶 2024-10-02 21:53:45

至少在 PostgreSQL 中,您可以在 GROUP BY 子句中使用结果集中的列号:

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

当然,如果您以交互方式执行此操作并且编辑查询来更改结果中列的数量或顺序,这会变得很痛苦。但仍然。

At least in PostgreSQL you can use the column number in the resultset in your GROUP BY clause:

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

Of course this starts to be a pain if you are doing this interactively and you edit the query to change the number or order of columns in the result. But still.

沧笙踏歌 2024-10-02 21:53:45

我并不是要回答为什么会这样,只是想展示一种通过使用 CROSS APPLY 创建别名来解决 SQL Server 中的限制的方法。然后,您可以在 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

I'm not answering why it is so, but only wanted to show a way around that limitation in SQL Server by using CROSS APPLY to create the alias. You then use it in the GROUP BY clause, like so:

SELECT 
 itemName as ItemName,
 FirstLetter,
 Count(itemName)
FROM table1
CROSS APPLY (SELECT substring(itemName, 1,1) as FirstLetter) Alias
GROUP BY itemName, FirstLetter
温柔戏命师 2024-10-02 21:53:45

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

以下是有关 SQL Server 逻辑处理阶段

SQL Server doesn't allow you to reference the alias in the GROUP BY clause because of the logical order of processing. The GROUP BY clause is processed before the SELECT clause, so the alias is not known when the GROUP BY clause is evaluated. This also explains why you can use the alias in the ORDER BY clause.

Here is one source for information on the SQL Server logical processing phases.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文