使用来自 LEFT JOIN 的数据进行双 LEFT JOIN 后在最后过滤数据

问题描述 投票:0回答:1

有一张桌子:

CREATE TABLE users (
    id serial NOT NULL,
    firstname varchar(64) NOT NULL,
    lastname varchar(64) NOT NULL,
    kid integer NOT NULL
);

CREATE TABLE keys (
    id serial NOT NULL,
    key varchar(1024) NOT NULL,
    tid integer NOT NULL
);

CREATE TABLE terminals (
    id serial NOT NULL,
    name varchar(64) NULL,
    ipaddr integer NOT NULL
);

得到一个数据:

INSERT INTO users (firstname, lastname, kid) VALUES ('jas', 'wedrowniczek', 1);
INSERT INTO users (firstname, lastname, kid) VALUES ('mariusz', 'kolano', 2);
INSERT INTO users (firstname, lastname, kid) VALUES ('ziobro', 'zbigniew', 3);
INSERT INTO users (firstname, lastname, kid) VALUES ('kornel', 'makuszynski', 4);
INSERT INTO users (firstname, lastname, kid) VALUES ('henryk', 'sienkiewicz', 5);

INSERT INTO keys (key, tid) VALUES ('key1', 1);
INSERT INTO keys (key, tid) VALUES ('key2', 2);
INSERT INTO keys (key, tid) VALUES ('key3', 3);
INSERT INTO keys (key, tid) VALUES ('key4', 4);
INSERT INTO keys (key, tid) VALUES ('key4', 5);

INSERT INTO terminals (name, ipaddr) VALUES ('pokoj1', 180879367);
INSERT INTO terminals (name, ipaddr) VALUES ('pokoj2', 180879468);
INSERT INTO terminals (name, ipaddr) VALUES ('pokoj3', 288704395);
INSERT INTO terminals (name, ipaddr) VALUES (NULL, 288703396);
INSERT INTO terminals (name, ipaddr) VALUES ('pokoj5', 0);

我需要获取所有具有终端密钥但没有描述或 ip 地址的登录信息。

结果应该是:

 id | firstname |   lastname   |  ipaddr   | name    |
----+-----------+--------------+-----------+----------
  4 | kornel    | makuszynski  | 288703396 |         |
  5 | henryk    | sienkiewicz  | 0         | pokoj5  |

我的尝试:

SELECT u.id, u.firstname, u.lastname, t.ipaddr, t.name
FROM users u
LEFT JOIN keys k ON (u.kid = k.id)
LEFT JOIN terminals t ON (t.id = k.tid)
WHERE
    t.ipaddr = 0
    OR t.name IS NULL;

它给了我空结果。

我明白: 首先是 SELECT 然后使用 WHERE 然后 LEFT JOIN 完成过滤。

...但是是否可以使用来自 LEFT JOIN 的数据在最后添加一些过滤?

sql postgresql left-join
1个回答
0
投票

当您创建

terminals
时,您指定了
NOT NULL
,然后尝试将名称插入为
NULL
。此外,最好在加入表之前过滤数据。

with t as (
select *
from   terminals 
where  ipaddr = 0 
   or  name is null 
)

select u.id 
      ,u.firstname 
      ,u.lastname   
      ,t.ipaddr   
      ,t.name    
from   users u join keys k using(id) join t on k.tid = t.id
id 名字 姓氏 ip地址 姓名
4 内核 马库申斯基 288703396
5 亨里克 显克微支 0 pokoj5

小提琴

© www.soinside.com 2019 - 2024. All rights reserved.