我有一个 SQL 查询,其别名与其子查询的某些别名相同。
例如:
select *
from ROOM r
where ...
(
select *
from ROAD r
where ...
)
Run Code Online (Sandbox Code Playgroud)
这很好用,因为子查询的别名似乎隐藏了主要的。
r?给定一个users包含两个字段的表:id和email。
select id, email as electronic_mail
from (
select id, email
from users
) t
where electronic_mail = ''
Run Code Online (Sandbox Code Playgroud)
Postgres 抱怨说:
Run Code Online (Sandbox Code Playgroud)ERROR: column "electronic_mail" does not exist
这个例子只是为了说明出现的问题。我的实际情况更复杂,我遍历 json 列中的元素数组,从每个元素中获取一个标量值。(如果有帮助,我可以分享一些代码。)
我真的不明白会有什么并发症,可能我不知道什么。我的印象是可以在WHERE子句中使用别名列而没有问题?
在尝试编写查询时,我发现(困难的方法)SQL Server 在执行查询时解析 SELECT 之前很久就解析了查询中的 WHERE。
的MSDN文档说,一般逻辑解析顺序是这样的:SELECT被解析几乎最后(因此导致“没有这样的对象[别名]”试图使用在其他条款列别名时误差)。甚至有人建议允许在任何地方使用别名,但被微软团队驳回,理由是 ANSI 标准合规性问题(这表明这种行为是 ANSI 标准的一部分)。
作为一名程序员(不是 DBA),我发现这种行为有些令人困惑,因为在我看来它在很大程度上违背了拥有列别名的目的(或者,至少,如果列别名是在查询执行中更早地解析),因为您可以实际使用别名的唯一地方是在 ORDER BY 中。作为一名程序员,它似乎错过了使查询更强大、更方便和 DRY 的巨大机会。
看起来这是一个如此明显的问题,它有理由认为,除了 SELECT 和 ORDER BY 之外,还有其他原因决定不允许列别名,但这些原因是什么?
我知道我必须写SUM两次,如果我想在HAVING子句中使用它(否则使用派生表):
SELECT id,
sum(hours) AS totalhours
FROM mytable
GROUP BY id
HAVING sum(hours) > 50;
Run Code Online (Sandbox Code Playgroud)
我现在的问题是,这是否是次优的。作为程序员,这个查询看起来 DB 会计算两次总和。是这样,还是我应该依赖数据库引擎将为我做的优化?
更新:可比查询的解释:
postgres=> explain select sum(counttodo) from orderline group by orderlineid having sum(counttodo) > 100;
QUERY PLAN
--------------------------------------------------------------------
HashAggregate (cost=1.31..1.54 rows=18 width=8)
Filter: (sum(counttodo) > 100)
-> Seq Scan on orderline (cost=0.00..1.18 rows=18 width=8)
(3 rows)
Run Code Online (Sandbox Code Playgroud) 当使用 SQL Server Management Studio for SQL Server 2008 R2 连接到本地 SQL Server 2008 R2 实例(版本 10.50.2500)时,我知道如果我使用实例名称(local)\sql2008,它将无法将调试器附加到我尝试执行的任何查询使用错误消息进行调试
无法启动 T-SQL 调试。无法连接到计算机“(本地)”。请求的名称有效,但未找到请求类型的数据。
但是,如果我更改src\sql2008与调试器的连接,则可以愉快地运行。
(local)除了我上面指出的调试器问题之外,让您的连接使用别名还有其他区别吗?
在过去的几年里,我花了很多时间来搜索、研究和实现各种复杂的 MySQL 查询。他们中的许多人为表使用了很多别名,即使没有必要也是如此。
为什么是这样?我看到了一些关于使用别名来提高可读性的讨论,但除了聚合/计算列之外,我发现它主要不利于可读性。您的大脑必须在别名和实际表之间进行转换。
例如:
SELECT orders.id, COUNT(*)
FROM orders, order_items
WHERE order_items.order_id = orders.id
GROUP BY orders.id
HAVING COUNT(*) > 1
Run Code Online (Sandbox Code Playgroud)
对比
SELECT o.id, COUNT(*)
FROM orders o, order_items i
WHERE i.order_id = o.id
GROUP BY o.id
HAVING COUNT(*) > 1
Run Code Online (Sandbox Code Playgroud)
对我来说,第一个版本更容易阅读,这只是一个简单的例子。但我看到它在简单的例子中使用了很多。只是打字少吗?因为这是一个可怕的理由。
我知道如果你一次或多次加入同一张桌子是有道理的,但在很多时候完全不是这样。
或者只是我缺少什么?
FROM提供column_alias,SQL 规范调用这些<derived column list>子句。这就是 postgres 文档对它们的描述,
FROM包含别名的项目的替代名称。别名用于简洁或消除自联接(多次扫描同一个表)的歧义。当提供别名时,它完全隐藏了表或函数的实际名称;例如 givenFROM foo AS f, 的其余部分SELECT必须将此FROM项目称为fnotfoo。如果编写了别名,还可以编写列别名列表来为表的一列或多列提供替代名称。
什么时候需要这些?我什么时候不能只使用 COLUMN 别名?
SELECT t.*
FROM table_name AS t (a,b,c);
Run Code Online (Sandbox Code Playgroud)
对比
SELECT t.col1 AS a, t.col2 AS b, t.col3 AS c
FROM table_name AS t;
Run Code Online (Sandbox Code Playgroud)
这个例子取自@ypercube 选择的答案??这似乎不太有用。
上述上下文中的 FROM 别名不会提供真正的好处,除非您是
这样做似乎依赖于常规t.*堆叠的危害,并增加了晦涩。那么什么时候FROM别名有用呢?
我使用 JOIN 语句从多个表中查询数据,如下所示:
SELECT u.id,u.name,d.id,d.name FROM user u RIGHT JOIN dog d ON... ;
Run Code Online (Sandbox Code Playgroud)
当我得到答案时,例如在 psql 中,我得到了这种行标题:
| id | name | id | name |
+-------+-------+------+--------+
Run Code Online (Sandbox Code Playgroud)
相反,我想获得原始和精确的符号:
| u.id | u.name | d.id | d.name |
+---------+---------+--------+----------+
Run Code Online (Sandbox Code Playgroud)
现在我必须使用AS语句,但重写它是非常重复的,它增加了查询的长度并降低了它的可读性。
有没有办法用 SQL 关键字或 DBMS 参数获得这个结果?
我进行了搜索,但无法找到有关此特定问题的任何信息。
我正在阅读 Postgres 文档和 SELECT 语句页面,并且遇到了我从未遇到过的别名方面。
在关于 FROM 子句的部分,副标题alias 中,有一句话说明:
如果编写了别名,还可以编写列别名列表来为表的一列或多列提供替代名称。
我能找到的文档中没有给出示例。
我知道如何将输出名称设置为别名,但这似乎不是一回事。
SELECT 的概要包括以下几行:
... SELECT [ ALL | DISTINCT [ ON (expression[, ...] ) ] ] * |expression[ [ AS ]output_name] [, ...] [ FROMfrom_item[, ...] ] ...
并定义from_item为:
其中 from_item 可以是以下之一:
[ ONLY ]table_name[ * ] [ [ AS ]alias[ (column_alias[, ...] ) ] ] (select) …
我有 2 个 SQL 表:NAMES并且RELATIONSHIPS目前NAMES只有 2 列:name和name_id。另一个是表中人与人之间的关系列表NAMES。它有 3 列:primaryperson_id、relatedperson_id和relationship_id。和primaryperson_id是表中related_person_id的。中的每个人都可以在 的主要列或相关列中拥有多个条目(这是多对多关系吗?)。name_idNAMESNAMESRELATIONSHIPS
此查询有效:
SELECT people.name AS 'primary', relationships.related_person_id AS relatedto
FROM relationships
JOIN people
ON people.name_id=relationships.primary_person_id
ORDER BY people.name_id;
Run Code Online (Sandbox Code Playgroud)
但我想在relatedto列中显示名称(即文本)而不是 ID 号。我怎样才能做到这一点?
alias ×10
postgresql ×5
sql-server ×3
subquery ×2
aggregate ×1
mysql ×1
ssms ×1
t-sql ×1
where ×1