Как SQL-запрос преобразует данные? - PullRequest
0 голосов
/ 23 июня 2019

Я наткнулся на этот вопрос и пытался понять, как ответ , заданный там, на самом деле преобразует данные.

Таблица ввода

+---------+-------+---------------+
| user_id | State | Subscriptions |
+---------+-------+---------------+
|       1 | LA    |             4 |
|       2 | LA    |             4 |
|       3 | LA    |            12 |
|       4 | LA    |            12 |
|       5 | LA    |             8 |
|       6 | LA    |             3 |
|       7 | NY    |            14 |
|       8 | NY    |            15 |
|       9 | NY    |             3 |
|      10 | NY    |             2 |
|      11 | NY    |             4 |
|      12 | NY    |            12 |
|      13 | OH    |             6 |
|      14 | OH    |             8 |
|      15 | OH    |             2 |
|      16 | OH    |             3 |
+---------+-------+---------------+

Таблица вывода

+--------------------+----+----+----+
| Subscription_Range | LA | NY | OH |
+--------------------+----+----+----+
| 1 to 4             |  3 |  3 |  2 |
| 5 to 11            |  1 |  0 |  2 |
| 12 to 15           |  2 |  3 |  0 |
+--------------------+----+----+----+

Ответ от Гордон Линофф :

 select (case when subscriptions <= 4 then '1 to 4'
                 when subscriptions <= 11 then '5 to 11'
                 when subscriptions <= 15 then '12 to 15'
            end) as subscription_range,
           sum(case when state = 'LA' then 1 else 0 end) as LA,
           sum(case when state = 'NY' then 1 else 0 end) as NY,
           sum(case when state = 'OH' then 1 else 0 end) as OH
    from t
    group by (case when subscriptions <= 4 then '1 to 4'
                   when subscriptions <= 11 then '5 to 11'
                   when subscriptions <= 15 then '12 to 15'
              end)
    order by min(subscriptions);

Я хотелпонять основы выполнения этого запроса.

Например:

  1. Когда будет выбрана первая строка, будет ли сначала проверяться столбец Subscriptions?(Поскольку это первое, что проверяется с помощью case в запросе.)
  2. После проверки выясняется, что ему следует присвоить 1 to 4.Что дальше?
  3. Будет ли проверяться столбец состояния?Оказывается, это LA, но я не понимаю, как происходит дальнейшее выполнение.Я пытаюсь представить, как формируется таблица перед агрегацией.

Работает ли SQL построчно?Например, каждая строка выбирается из базы данных, и соответствующая часть запроса применяется к каждому столбцу?(Например, case применяется к столбцу Subscriptions в этом случае.)

Ответы [ 2 ]

1 голос
/ 23 июня 2019

При оценке выражений в предложении select до агрегирования можно представить, что для данного набора данных будет получена следующая таблица:

+--------------------+-----+----+----+
| subscription_range | LA  | NY | OH |
+--------------------+-----+----+----+
| '1 to 4'           |   1 |  0 |  0 |
| '1 to 4'           |   1 |  0 |  0 |
| '12 to 15'         |   1 |  0 |  0 |
| '12 to 15'         |   1 |  0 |  0 |
| '5 to 11'          |   1 |  0 |  0 |
| '1 to 4'           |   1 |  0 |  0 |
| '12 to 15'         |   0 |  1 |  0 |
| '12 to 15'         |   0 |  1 |  0 |
| '1 to 4'           |   0 |  1 |  0 |
| '1 to 4'           |   0 |  1 |  0 |
| '1 to 4'           |   0 |  1 |  0 |
| '12 to 15'         |   0 |  1 |  0 |
| '5 to 11'          |   0 |  0 |  1 |
| '5 to 11'          |   0 |  0 |  1 |
| '1 to 4'           |   0 |  0 |  1 |
| '1 to 4'           |   0 |  0 |  1 |
+--------------------+-----+----+----+

Здесь для каждой строки в наборе данных первый оператор case возвращает строку, а последующие операторы case дают либо 1, либо 0 в зависимости от того, проверяет ли тест столбец state выражение.

При агрегировании запрос вычисляет тот же набор subscription_range значений и groups by этих данных, что каждый subscription_range отличается.

Оставшиеся числовые данные в последующих столбцах затем суммируются по каждой группе с помощью выражений sum, включающих каждый оператор case, что дает:

+--------------------+----+----+----+
| subscription_range | LA | NY | OH |
+--------------------+----+----+----+
| 1 to 4             |  3 |  3 |  2 |
| 5 to 11            |  1 |  0 |  2 |
| 12 to 15           |  2 |  3 |  0 |
+--------------------+----+----+----+
1 голос
/ 23 июня 2019

В первом случае, когда подписки просто выдают значение для псевдонима диапазона, ключи, используемые для группировки по 3 частям, например, LA, NY, OH, используют поддельную функцию агрегирования для имитации сводной таблицы

без подделкиФункция агрегации каждого значения размещается в разных строках. Использование группы позволяет свести все строки с одинаковым диапазоном к одиночным строкам. Получив желаемое соотношение

 select (case when subscriptions <= 4 then '1 to 4'
             when subscriptions <= 11 then '5 to 11'
             when subscriptions <= 15 then '12 to 15'
        end) as subscription_range,
       sum(case when state = 'LA' then 1 else 0 end) as LA,
       sum(case when state = 'NY' then 1 else 0 end) as NY,
       sum(case when state = 'OH' then 1 else 0 end) as OH
from t
group by (case when subscriptions <= 4 then '1 to 4'
               when subscriptions <= 11 then '5 to 11'
               when subscriptions <= 15 then '12 to 15'
          end)
order by min(subscriptions);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...