我是初级Web开发人员。我正在研究postgres,并且对案例陈述的用例有疑问。
此查询将找到几行数据与特定单词最匹配的行。
结果可以是多个。
在此查询中,排名值是根据每个行的相似性使用case语句计算的。
可以理解,case语句返回与每次执行相匹配的值。
当在min和window函数中使用case语句时,我想知道如何找到结果。
给定的表PostalCode是..
|---------------------|------------------|
| pcode | name |
|---------------------|------------------|
| 100456 | a |
|---------------------|------------------|
| 111343 | b |
|---------------------|------------------|
| 101334 | c |
|---------------------|------------------|
| 100567 | d |
|---------------------|------------------|
| 102234 | e |
|---------------------|------------------|
查询是..
SELECT pcode,
name
FROM (SELECT pcode,
name,
CASE WHEN pcode = '100123' THEN 0
WHEN pcode = '10012%' THEN 1
WHEN pcode = '1001%' THEN 2
WHEN pcode = '100%' THEN 3
WHEN pcode = '10%' THEN 4
WHEN pcode = '1%' THEN 5
ELSE NULL END AS hit_code,
MIN(CASE WHEN pcode = '100123' THEN 0
WHEN pcode = '10012%' THEN 1
WHEN pcode = '1001%' THEN 2
WHEN pcode = '100%' THEN 3
WHEN pcode = '10%' THEN 4
WHEN pcode = '1%' THEN 5
ELSE NULL END)
OVER(ORDER BY CASE WHEN pcode = '100123' THEN 0
WHEN pcode = '10012%' THEN 1
WHEN pcode = '1001%' THEN 2
WHEN pcode = '100%' THEN 3
WHEN pcode = '10%' THEN 4
WHEN pcode = '1%' THEN 5
ELSE NULL END) AS min_code,
FROM PostalCODE) Foo
WHERE hit_code = min_code;
结果将是
|---------------------|------------------|
| pcode | name |
|---------------------|------------------|
| 100456 | a |
|---------------------|------------------|
| 100567 | d |
|---------------------|------------------|
我知道第一个case语句根据相似性返回不同的值。
案例结束后,将调用MIN函数,但是它将返回什么?
我无法理解这种情况。
请帮助我。
如果您能帮助我,我什么也不能给您,但我要表示我诚挚的谢意。
感谢阅读。
您的大小写表达式检查给定p_code
和固定代码之间的相似性,并返回hit_code
,即0(最高相似性)和5(最低相似性)或null
(完全没有相似性)之间的值。
窗口函数min() over()
对整个数据集执行非常相同的操作:它为您提供整个表的最小 hit_code
。
最后,外部查询对具有最小hit_code
(即,最高相似性)的记录进行过滤。
代码可能存在的问题:
窗口函数应该有一个空的over()
子句(order by
无效)
模式匹配需要运算符like
而不是=
请注意,可以直接使用排名函数来缩短代码:
select pcode, name
from (
select
t.*,
rank() over(
order by case
when pcode = '100123' then 0
when pcode like '10012%' then 1
when pcode like '1001%' then 2
when pcode like '100%' then 3
when pcode like '10%' then 4
when pcode like '1%' then 5
else null
end)
as hit_rank
from mytable t
) t
where hit_rank = 1
如果只想排一行,那会简单得多:
SELECT pcode, name
FROM PostalCODE pc CROSS JOIN LATERAL
(CASE WHEN pcode = '100123' THEN 0
WHEN pcode = '10012%' THEN 1
WHEN pcode = '1001%' THEN 2
WHEN pcode = '100%' THEN 3
WHEN pcode = '10%' THEN 4
WHEN pcode = '1%' THEN 5
END) v(hit_code)
ORDER BY hit_code ASC
LIMIT 1;