Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PostgreSQL多重使用子句_Sql_Postgresql_Using - Fatal编程技术网

PostgreSQL多重使用子句

PostgreSQL多重使用子句,sql,postgresql,using,Sql,Postgresql,Using,我经常发现自己在PostgreSQL中使用using子句(并非有意使用双关语),我想知道如果在同一个密钥名上多次使用,该如何选择 让我用一个简单的例子来解释: 让表A、B和C具有userid列。 如果我正在做: SELECT A.c1, A.c2, ... FROM A JOIN B USING(userid) JOIN C USING(userid) ; Postrges如何管理由于表B和表C都有列userid这一事实而产生的冲突?结果是什么 A.userid = B.userid AND

我经常发现自己在PostgreSQL中使用using子句(并非有意使用双关语),我想知道如果在同一个密钥名上多次使用,该如何选择

让我用一个简单的例子来解释: 让表A、B和C具有userid列。 如果我正在做:

SELECT A.c1, A.c2, ...
FROM A
JOIN B USING(userid)
JOIN C USING(userid) ;
Postrges如何管理由于表B和表C都有列userid这一事实而产生的冲突?结果是什么

A.userid = B.userid AND A.userid = C.userid

我希望我已经足够清楚了,提前谢谢你的回答


PS:我没有使用multiple-USING子句,因为我发现它不可读,但我想知道它是如何工作的。

如果您使用
USING
,那么连接结果中只有一个
用户ID,因此不会有歧义

我要说的是

此外,
JOIN USING
的输出会抑制冗余列:


但它也引用了列引用。您可以在没有表限定的情况下使用
userid
,并且不会出现“不明确的列引用”错误,因为PostgreSQL知道该列只存在一次。

对于内部联接,此查询:

SELECT A.c1, A.c2, ...
FROM A JOIN
     B
     USING (userid) JOIN
     C
     USING (userid) ;
相当于:

SELECT A.c1, A.c2, ...
FROM A JOIN
     B
     ON B.userid = A.userid JOIN
     C
     ON C.userid = A.userid ;  -- or "C.userid = B.userid", it doesn't matter
请注意,
NULL
值无法比较
内部联接
,因此它们不是问题,因为它们不在结果集中

对于
左外连接
,逻辑与上述相同。对于
完全联接

SELECT A.c1, A.c2, ...
FROM A FULL JOIN
     B
     ON B.userid = A.userid FULL JOIN
     C
     ON C.userid = COALESCE(A.userid, B.userid) ;  

请注意,在查询的其余部分中,
userid
,不带任何限定,指的是任何表中的非
NULL
值。

您可以解释计划并检查:

CREATE TABLE a (
  userid INT
, nm VARCHAR(32)
);
CREATE TABLE b (
  userid INT
, adr VARCHAR(32)
);
CREATE TABLE c (
  userid INT
, car VARCHAR(32)
);

EXPLAIN
SELECT *
FROM a
JOIN b USING(userid)
JOIN c USING(userid)
;
-- out                               QUERY PLAN                               
-- out -----------------------------------------------------------------------
-- out  Merge Join  (cost=152.17..334.01 rows=8946 width=250)
-- out    Merge Cond: (a.userid = c.userid)
-- out    ->  Merge Join  (cost=101.45..142.80 rows=2520 width=172)
-- out          Merge Cond: (a.userid = b.userid)
-- out          ->  Sort  (cost=50.72..52.50 rows=710 width=86)
-- out                Sort Key: a.userid
-- out                ->  Seq Scan on a  (cost=0.00..17.10 rows=710 width=86)
-- out          ->  Sort  (cost=50.72..52.50 rows=710 width=86)
-- out                Sort Key: b.userid
-- out                ->  Seq Scan on b  (cost=0.00..17.10 rows=710 width=86)
-- out    ->  Sort  (cost=50.72..52.50 rows=710 width=86)
-- out          Sort Key: c.userid
-- out          ->  Seq Scan on c  (cost=0.00..17.10 rows=710 width=86)

-- and with a full outer join:

EXPLAIN
SELECT *
FROM a
FULL JOIN b USING(userid)
FULL JOIN c USING(userid)
;
-- out                                  QUERY PLAN                                  
-- out -----------------------------------------------------------------------------
-- out  Merge Full Join  (cost=326.16..463.90 rows=8946 width=250)
-- out    Merge Cond: (c.userid = (COALESCE(a.userid, b.userid)))
-- out    ->  Sort  (cost=50.72..52.50 rows=710 width=86)
-- out          Sort Key: c.userid
-- out          ->  Seq Scan on c  (cost=0.00..17.10 rows=710 width=86)
-- out    ->  Sort  (cost=275.43..281.73 rows=2520 width=172)
-- out          Sort Key: (COALESCE(a.userid, b.userid))
-- out          ->  Hash Full Join  (cost=25.98..133.06 rows=2520 width=172)
-- out                Hash Cond: (a.userid = b.userid)
-- out                ->  Seq Scan on a  (cost=0.00..17.10 rows=710 width=86)
-- out                ->  Hash  (cost=17.10..17.10 rows=710 width=86)
-- out                      ->  Seq Scan on b  (cost=0.00..17.10 rows=710 width=86)


JOIN C USING(userid)
使用上一次连接中唯一的一个userid,既不是A也不是B。您的问题涉及查询的处理顺序。如前所述,解释计划将向您显示系统上的流程以及当前的数据量。然而,这个顺序并不是固定的。优化器根据可用索引、表大小、当前统计信息等选择操作顺序。当这些更改时,计划本身(可能)也会更改。只要这些连接是内部连接就可以了,但是如果连接是外部连接呢?至少语法允许。然后您得到非空值。谢谢。有道理,我刚刚检查了SQL标准,结果实际上是使用COALESCE定义的。
CREATE TABLE a (
  userid INT
, nm VARCHAR(32)
);
CREATE TABLE b (
  userid INT
, adr VARCHAR(32)
);
CREATE TABLE c (
  userid INT
, car VARCHAR(32)
);

EXPLAIN
SELECT *
FROM a
JOIN b USING(userid)
JOIN c USING(userid)
;
-- out                               QUERY PLAN                               
-- out -----------------------------------------------------------------------
-- out  Merge Join  (cost=152.17..334.01 rows=8946 width=250)
-- out    Merge Cond: (a.userid = c.userid)
-- out    ->  Merge Join  (cost=101.45..142.80 rows=2520 width=172)
-- out          Merge Cond: (a.userid = b.userid)
-- out          ->  Sort  (cost=50.72..52.50 rows=710 width=86)
-- out                Sort Key: a.userid
-- out                ->  Seq Scan on a  (cost=0.00..17.10 rows=710 width=86)
-- out          ->  Sort  (cost=50.72..52.50 rows=710 width=86)
-- out                Sort Key: b.userid
-- out                ->  Seq Scan on b  (cost=0.00..17.10 rows=710 width=86)
-- out    ->  Sort  (cost=50.72..52.50 rows=710 width=86)
-- out          Sort Key: c.userid
-- out          ->  Seq Scan on c  (cost=0.00..17.10 rows=710 width=86)

-- and with a full outer join:

EXPLAIN
SELECT *
FROM a
FULL JOIN b USING(userid)
FULL JOIN c USING(userid)
;
-- out                                  QUERY PLAN                                  
-- out -----------------------------------------------------------------------------
-- out  Merge Full Join  (cost=326.16..463.90 rows=8946 width=250)
-- out    Merge Cond: (c.userid = (COALESCE(a.userid, b.userid)))
-- out    ->  Sort  (cost=50.72..52.50 rows=710 width=86)
-- out          Sort Key: c.userid
-- out          ->  Seq Scan on c  (cost=0.00..17.10 rows=710 width=86)
-- out    ->  Sort  (cost=275.43..281.73 rows=2520 width=172)
-- out          Sort Key: (COALESCE(a.userid, b.userid))
-- out          ->  Hash Full Join  (cost=25.98..133.06 rows=2520 width=172)
-- out                Hash Cond: (a.userid = b.userid)
-- out                ->  Seq Scan on a  (cost=0.00..17.10 rows=710 width=86)
-- out                ->  Hash  (cost=17.10..17.10 rows=710 width=86)
-- out                      ->  Seq Scan on b  (cost=0.00..17.10 rows=710 width=86)