我有很多看起来像这样的表格:
CREATE TABLE table1(id INTEGER PRIMARY KEY, t1c1 INTEGER, t1c2 INTEGER);
CREATE TABLE table2(id INTEGER PRIMARY KEY, t1 INTEGER REFERENCES table1(id), t2c1 INTEGER);
Run Code Online (Sandbox Code Playgroud)
我做了很多连接,我试图过滤连接表以从第一个表中获取内容,如下所示:
SELECT t1c1
FROM table1
JOIN table2 ON table2.t1 = table1.id
WHERE t2c1 = 42;
Run Code Online (Sandbox Code Playgroud)
当我为表编写索引时,我会查看 WHERE 子句中使用的列并构建索引以满足它们。所以对于这个查询,我最终会写一个这样的索引:
CREATE INDEX ON table2 (t2c1);
Run Code Online (Sandbox Code Playgroud)
并且这个索引至少有资格在该查询中使用。
我的问题是,如果我写这样的索引:
CREATE INDEX ON table2 (t2c1, t1);
Run Code Online (Sandbox Code Playgroud)
索引会不会作为覆盖索引来帮助上面查询中的JOIN?我应该改变我的索引编写策略来覆盖外键列吗?
给定band
表格,其中一json
列包含一个数组:
id | people
---+-------------
1 | ['John', 'Thomas']
2 | ['John', 'James']
3 | ['James', 'George']
Run Code Online (Sandbox Code Playgroud)
如何列出每个名称所属的乐队数量?
期望的输出:
name | count
-------+------------
John | 2
James | 2
Thomas | 1
George | 1
Run Code Online (Sandbox Code Playgroud) FROM
提供column_alias
,SQL 规范调用这些<derived column list>
子句。这就是 postgres 文档对它们的描述,
FROM
包含别名的项目的替代名称。别名用于简洁或消除自联接(多次扫描同一个表)的歧义。当提供别名时,它完全隐藏了表或函数的实际名称;例如 givenFROM foo AS f
, 的其余部分SELECT
必须将此FROM
项目称为f
notfoo
。如果编写了别名,还可以编写列别名列表来为表的一列或多列提供替代名称。
什么时候需要这些?我什么时候不能只使用 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
别名有用呢?
在这个答案中,我解释了 SQL-89 的隐式语法。
但是我在玩的时候注意到不同的查询计划:
EXPLAIN ANALYZE
SELECT *
FROM (values(1)) AS t(x), (values(2)) AS g(y);
QUERY PLAN
------------------------------------------------------------------------------------
Result (cost=0.00..0.01 rows=1 width=0) (actual time=0.002..0.002 rows=1 loops=1)
Planning time: 0.052 ms
Execution time: 0.020 ms
(3 rows)
Run Code Online (Sandbox Code Playgroud)
与此相反:
EXPLAIN ANALYZE
SELECT *
FROM (values(1)) AS t(x)
CROSS JOIN (values(2)) AS g(y);
QUERY PLAN
------------------------------------------------------------------------------------------------
Subquery Scan on g (cost=0.00..0.02 rows=1 width=4) (actual time=0.004..0.005 rows=1 loops=1)
-> Result (cost=0.00..0.01 rows=1 width=0) (actual time=0.002..0.002 rows=1 loops=1)
Planning time: 0.075 ms
Execution time: 0.027 …
Run Code Online (Sandbox Code Playgroud) postgresql performance join execution-plan postgresql-9.5 postgresql-performance
在 Oracle 中,我使用
SELECT * FROM table1...JOIN...
Run Code Online (Sandbox Code Playgroud)
其中点表示连接类型或连接条件。
这是 ANSI 89 语法吗?如果没有,那么如果我使用 ANSI 89,我将如何执行连接?
通常这样写很方便:
SELECT *
FROM t1 # ... +many more tables
INNER JOIN t2 ON (t1.id = t2.col)
INNER JOIN t3 ON (t1.id = t3.col)
INNER JOIN t4 ON (t1.id = t4.col)
...
Run Code Online (Sandbox Code Playgroud)
作为带条件的交叉连接:
SELECT *
FROM t1, t2, t3, t4 # ... +many more tables
WHERE
t1.id = t2.col
AND t1.id = t3.col
AND t1.id = t4.col
# +include matches on columns of other tables
Run Code Online (Sandbox Code Playgroud)
但是,交叉连接的简单实现将比内部连接具有更高的时间复杂度。Postgres 是否将第二个查询优化为与第一个查询具有相同时间复杂度的查询?
我收到此错误:
当我尝试执行以下查询时出现:
with expensive_service as (
select s1.*
from service s1, service s2
where s1.price > s2.price
)
select *
from service except expensive_service;
Run Code Online (Sandbox Code Playgroud)
我试图实现WITH ... AS
(链接到 PostgreSQL 文档)。
此查询为我提供了所需的输出:
select *
from service except (
select s1.*
from service s1, service s2
where s1.price > s2.price
)
Run Code Online (Sandbox Code Playgroud)
任何指导我错误所在的帮助将不胜感激!
postgresql ×6
join ×3
alias ×1
array ×1
cte ×1
except ×1
group-by ×1
index ×1
json ×1
optimization ×1
performance ×1
sql-standard ×1