在postgresql的min函数中使用case语句的情况下如何工作?

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

我是初级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函数,但是它将返回什么?

我无法理解这种情况。

请帮助我。

如果您能帮助我,我什么也不能给您,但我要表示我诚挚的谢意。

感谢阅读。

sql postgresql case-statement
1个回答
0
投票

您的大小写表达式检查给定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

0
投票

如果只想排一行,那会简单得多:

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;
© www.soinside.com 2019 - 2024. All rights reserved.