Как это работает в случае использования оператора case внутри функции min в postgresql? - PullRequest
1 голос
/ 03 марта 2020

Я младший веб-разработчик. Я изучаю около postgres, и у меня есть вопрос об использовании case-оператора.

Этот запрос находит несколько строк с данными, которые наиболее точно соответствуют определенному слову.

Результат может быть кратным.

В этом запросе значение ранжирования вычисляется с использованием оператора case в соответствии с подобием для каждой строки.

Понятно, что оператор case возвращает значение, соответствующее каждому выполнению.

Когда оператор case используется внутри функций min и window, мне интересно, как найти результат.

данная таблица 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, но что она вернет?

Я не могу понять этот контекст.

Пожалуйста, помогите мне.

Если вы мне поможете, я ничего не могу вам дать, но я бы хотел express выразить искреннюю благодарность.

Спасибо за чтение.

Ответы [ 2 ]

0 голосов
/ 03 марта 2020

Если вы хотите только одну строку, это будет намного проще, чем:

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;
0 голосов
/ 03 марта 2020

Ваше выражение case проверяет сходство между данным p_code и фиксированным кодом и возвращает hit_code, значение между 0 (наибольшее сходство) и 5 ​​(самое низкое сходство), или null (вообще нет сходства) ).

Оконная функция min() over() выполняет одну и ту же операцию для всего набора данных: она дает минимум hit_code для всей таблицы.

Наконец внешние фильтры запрашивают записи (записи) с минимальным значением hit_code (ie наибольшее сходство).

Потенциальные проблемы с кодом:

  • оконная функция должна иметь пустое предложение 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...