SQLite: Как работает порядок выполнения с учетом подзапроса CASE WHEN? - PullRequest
0 голосов
/ 05 января 2020

Приведенный ниже код является частью рабочей тяги SQLite. Может кто-нибудь объяснить, как работает раздел КОГДА? Он использует подзапрос в скобках. Я думал, что подзапрос будет выполняться до внешнего запроса. В таком случае, как может работать country = c.country? Разве c .country не существует только после выполнения внешнего запроса?

WITH country_or_other AS
    (
     SELECT
       CASE
           WHEN (
                 SELECT count(*)
                 FROM customer
                 where country = c.country
                ) = 1 THEN "Other"
           ELSE c.country
       END AS country,
       c.customer_id,
       il.*
     FROM invoice_line il
     INNER JOIN invoice i ON i.invoice_id = il.invoice_id
     INNER JOIN customer c ON c.customer_id = i.customer_id
    )

Ответы [ 2 ]

0 голосов
/ 05 января 2020

В каждой строке вашего запроса есть столбец c.country из объединенной таблицы customer. Таким образом, для каждой строки вашего запроса этот запрос:

SELECT count(*)
FROM customer
where country = c.country

выполняется и возвращает количество строк в таблице customer, где столбец country равен значению c.country. Это число сравнивается с 1, а выражение CASE возвращает либо 'Other', либо значение c.country. Вот как я мог бы написать этот код:

WITH country_or_other AS
    (
     SELECT
       CASE
           WHEN t.counter = 1 THEN "Other"
           ELSE c.country
       END AS country,
       c.customer_id,
       il.*
     FROM invoice_line il
     INNER JOIN invoice i ON i.invoice_id = il.invoice_id
     INNER JOIN customer c ON c.customer_id = i.customer_id
     INNER JOIN (SELECT country, count(*) counter FROM customer GROUP BY country) t ON t.country = c.country 
    )

Я предполагаю, что столбец country в таблице customer не NULL.

0 голосов
/ 05 января 2020

У вас есть коррелированный подзапрос. Концептуально подзапрос выполняется для каждой строки, сгенерированной внешним запросом. Каждый прогон имеет свое значение для внешней ссылки.

Однако коррелированный подзапрос не требуется:

SELECT (CASE WHEN COUNT(*) OVER (PARTITION BY c.country) = 1
             THEN 'Other'
             ELSE c.country
        END) AS country,
        c.customer_id,
        il.*
 FROM invoice_line il JOIN
      invoice i 
      ON i.invoice_id = il.invoice_id JOIN
      customer c
      ON c.customer_id = i.customer_id
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...