Sła*_*art 5 postgresql order-by
我在 Postgres 表中有 6 列:
A1 character varying(5)[]
A2 character varying(5)[]
A3 int REFERENCES ... -- FK
B1 character varying(5)[]
B2 character varying(5)[]
B3 int REFERENCES ... -- FK
Run Code Online (Sandbox Code Playgroud)
我需要一个SELECT匹配的第一行是获胜者(限制为 1)并匹配 A 组和 B 组。
我知道 Postgres 不关心WHERE子句的顺序,我必须准备一个ORDER子句或找到不同的方法。
我想准备匹配优先级的查找,我的WHERE子句重要性如下:
highest priority: (A1 and B1) OR
. (A1 and B2 OR A2 and B1) OR
. (A1 and B3 OR A3 and B1) OR
. (A2 and B3 OR A3 and B2) OR
lowest priority: (A3 and B3)
Run Code Online (Sandbox Code Playgroud)
查询匹配 6 个值,例如:
a1 到 A1、a2 到 A2、a3 到 A3、b1 到 B1、b2 到 B2、b3 到 B3
所以A1 和 B1表示a1 与 A1 匹配,b1 与 B1 匹配,
在 SQL 这部分写成:
("A1" @> ARRAY['19956']::varchar(5)[] AND "B1" @> ARRAY['27407']::varchar(5)[])
a1='19956', b1='27407'。
尽管 SQL 具有声明性方面,但是否可以将其准备为单个查询?我正在考虑在同一张桌子上进行 5 个连接,但也许有更简单的方法。
此信息至关重要:
匹配的第一行是获胜者(限制为 1)
对于单个结果,您实际上不需要任何排序顺序。ORDER BY只是如何解决任务的一个想法。我建议采用完全不同的方法,可能(快得多):
SELECT * FROM tbl WHERE A1 AND B1
UNION ALL
SELECT * FROM tbl WHERE A1 AND B2 OR A2 and B1
UNION ALL
SELECT * FROM tbl WHERE A1 AND B3 OR A3 and B1
UNION ALL
SELECT * FROM tbl WHERE A2 AND B3 OR A3 and B2
UNION ALL
SELECT * FROM tbl WHERE A3 AND B3
LIMIT 1;
Run Code Online (Sandbox Code Playgroud)
这是假设每个SELECT只能返回一行。否则你会得到一个任意的选择,或者你需要添加ORDER BY到括号中的单个 SELECT 以获得确定性的选择。(请参阅下面的链接答案。)
它的美妙之处在于:一旦找到第一行,Postgres 就会停止评估。测试EXPLAIN ANALYZE以查看尾随 SELECT 的“从未执行过”。因此您可以使用索引,这可能意味着性能的数量级。
如果没有匹配项,您可以方便地返回默认行。SELECT之前再追加一个LIMIT 1。
顺便说一句,这是一个单一的查询。
有关的: