我有这张桌子:
CREATE TABLE clients (
id BIGSERIAL NOT NULL,
company CHARACTER VARYING(255) DEFAULT '' NOT NULL,
email CHARACTER VARYING(50) DEFAULT '' NOT NULL,
city CHARACTER VARYING(80),
postcode CHARACTER VARYING(20),
);
我得到了城市和邮政编码的列表。我需要查找是否有任何行与我拥有的数据匹配:
City,Zipcode
Lansdowne,2163
Villawood,2163
Smithfield,2164
我正在使用这个查询;我怎样才能达到预期的结果?
SELECT
t1.id,
t1.city,
t1.company,
t1.postcode
FROM
clients t1
LEFT JOIN
clients t2 ON t2.city = t1.city
LEFT JOIN
clients t3 ON t3.postcode = t1.postcode
WHERE t2.city IN ('Lansdowne','Villawood','Smithfield',)
AND t3.postcode IN ('2164','2163','2163',)
查询是否正确?
不,它会找到给定城市和邮政编码的任意组合(例如
('Smithfield', '2163')
。对于一个查询中的更多组合,此笛卡尔积将变得越来越昂贵且毫无意义。并且查询本身不必要地昂贵并且最重要的是令人困惑。
LEFT JOIN
放错了地方,不需要加入。匹配多行(多列值的组合)的最短、最干净和最快的方法是连接到一个
VALUES
表达式(这是一个临时表表达式):对于大表,为了加快速度,您应该有一个索引,
(city, postcode)
反之亦然,或者至少有一个以这两个列为前导列的索引。此查询返回数据,但如果结果相同,则此查询的原因是什么您可以在没有不必要的 JOIN 的情况下实现?
此查询与原始形式相同,不检查城市+邮政编码(允许任何组合),更强大的形式: