我最近被一个错误(在我的代码中)所困扰,其中这两个查询的运行时截然不同:
select * from smalltable st
inner join bigtable bt on st.btid = bt.btid
select * from bigtable bt
inner join smalltable st on bt.btid = st.btid
Run Code Online (Sandbox Code Playgroud)
以及单个查询在 where 过滤器中为不同的字符串寻找不同的执行计划。
是否有任何优化的、完全声明性的 SQL 标准实现,以便上述两个查询具有相同的执行计划?
在回答有关 stackoverflow 的问题时,我提出了派生表的定义:
派生表是一个完整的查询,在括号内,就像一个真正的表一样使用。
但有评论者反对:
尽管除了“括号内”之外还有其他类型的派生表。... [例如] 视图和表值函数 ... .
并进一步支持这一点:
来自 ISO/IEC 2003 规范,框架卷的第 4.3 节,2003 年 8 月规范草案的第 13 页:“引用零个或多个基表并返回表的操作称为查询。查询的结果称为一个派生表。” 请注意,视图和表值函数都返回“查询结果”,这是一个派生表。Microsoft(以及在较小程度上,Oracle)因其在其文档中错误地将“派生表”和“子查询”等同而臭名昭著,但派生表确实也包括预定义的查询,如视图。
那么真正的独家新闻是什么?我是将我认为的派生表降级为简单的“FROM 子句别名内联子查询”还是视图没有正确派生表?
请注意:我在网上搜索了很长一段时间,但找不到任何明确的内容。我没有上述规范的副本。
此外,我认为值得解决其他问题。假设视图被正确地称为“派生表”。这是否使对视图的引用也是“派生表”或仅仅是引用?对于一个 CTE 的例子,应该把这个点带回家:
WITH SalesTotals AS (
SELECT
O.CustomerID,
SalesTotal = Sum(OrderTotal)
FROM
dbo.CustomerOrder O
GROUP BY
O.CustomerID
)
SELECT
C.Name,
S.SalesTotal
FROM
dbo.Customer C
INNER JOIN SalesTotals S
ON C.CustomerID = S.CustomerID;
Run Code Online (Sandbox Code Playgroud)
SalesTotals引入的CTEWITH是一个派生表。但INNER JOIN SalesTotals 也是派生表,还是只是对派生表的引用?这个查询有两个派生表还是一个?如果一个人,然后推而广之,我认为,一个观点可能是一个派生表,但参考它可能不具备成为一个派生表。
我只是想知道 MariaDB 或 MySQL 是否<table value constructor>在 SQL 规范中实现了。在SQL Server和PostgreSQL 中,这是通过标准化的VALUES (expression)?
SELECT *
FROM ( VALUES (1) ) AS t(x);
x
---
1
(1 row)
Run Code Online (Sandbox Code Playgroud)
(来自postgresql 的语法)。
我知道NULLIF比较两个值并NULL在匹配时返回的函数。
是否有一个函数可以比较两个值并NULL在它们不匹配时返回?即过滤掉其他值。
我知道我可以使用CASE以下方法做类似的事情:
CASE column WHEN value THEN 1 END
Run Code Online (Sandbox Code Playgroud)
我也知道我可以写一个函数。
也许有一个NULLIF我不知道的微妙使用技巧。
我认为NULLIF是通用的。我正在寻找一个通用的解决方案,以便它可以应用于任何标准数据库。
在mysql 5.6中,考虑这 2 个在 A、B、C 和 D 之间创建关系的示例。
实施例1
CREATE TABLE `a` (
id INT UNSIGNED NOT NULL,
PRIMARY KEY (id)
) ENGINE = INNODB;
CREATE TABLE `b` (
id INT UNSIGNED NOT NULL,
a INT UNSIGNED NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (a) REFERENCES a (id) ON DELETE CASCADE
) ENGINE = INNODB;
CREATE TABLE `c` (
id INT UNSIGNED NOT NULL,
a INT UNSIGNED NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (a) REFERENCES a (id) …Run Code Online (Sandbox Code Playgroud) 在以下语句中(PostgreSQL 11):
=> SELECT c cost FROM tt;
ERROR: syntax error at or near "cost"
LINE 1: SELECT c cost FROM tt;
Run Code Online (Sandbox Code Playgroud)
我收到一个错误。在字段表达式周围添加括号没有帮助 ( SELECT (c) cost FROM tt;)。但添加AS关键字就可以解决这个问题。
=> SELECT c AS cost FROM tt;
cost
------
1
...
Run Code Online (Sandbox Code Playgroud)
我意识到这cost是一个关键字,但我的印象是该AS关键字是可选的。
从语言的角度来看,为什么AS这里需要(或有帮助)关键字?这里的 PostgreSQL 行为是标准的还是在某处记录的?
还有其他情况AS需要使用关键字吗?
我在这里查看 SQL 关键字列表https://www.postgresql.org/docs/current/sql-keywords-appendix.html
那里有一些单字母关键字。我找不到有关他们的任何信息。我在哪里可以找到这些信息以及这些信息的用途是什么?
例子,
A,C,F,G,K,M,P,T。
我目前正在学习 TSQL 并且正在学习这是可能的,我应该使用“标准”SQL 方言。我在哪里可以找到哪些命令是“标准”的,哪些是 TSQL?
是否有自动编号列的ANSI标准。
目前,我们有一个选择SERIAL,AUTOINCREMENT,AUTO_INCREMENT,IDENTITY()和良好的老NEXTVAL()等等。
我在某处读到有一个新标准IDENTITY,我知道 Oracle 最近实施了该标准。我知道 Oracle 并不是标准的硬道理。
如果有一个标准,那么它是一个很长的时间来。
sql-standard ×10
mysql ×2
postgresql ×2
cascade ×1
delete ×1
foreign-key ×1
mariadb ×1
mariadb-10.3 ×1
null ×1
operator ×1
optimization ×1
sql-server ×1
syntax ×1
t-sql ×1