Добавление условных операторов в оконную функцию SQL - PullRequest
0 голосов
/ 27 января 2020

Я хочу использовать ряд условий, чтобы определить, как работает моя оконная функция. В настоящее время у меня есть следующее:

SELECT col1, col2, 
   1=Row_number() OVER (PARTITION BY col1 ORDER BY col2 ASC) OR
   3=Row_number() OVER (PARTITION BY col1 ORDER BY col2 ASC)
   AS col3 
FROM   myTable;

По сути, он берет два столбца ввода, группирует по значениям в col1, упорядочивает по значениям в col2, а затем разбивает данные для каждого разбиения на две половины и помечая первую строку каждой половины как true / 1.

Итак, взяв этот ввод:

+------+------+
| col1 | col2 |
+------+------+
|    1 |    1 |
|    1 |    2 |
|    1 |    3 |
|    1 |    4 |
|    2 |    1 |
|    2 |    2 |
|    2 |    3 |
|    2 |    4 |
+------+------+

Получим следующий результат:

+------+------+------+
| col1 | col2 | col3 |
+------+------+------+
|    1 |    1 |    1 |
|    1 |    2 |    0 |
|    1 |    3 |    1 |
|    1 |    4 |    0 |
|    2 |    1 |    1 |
|    2 |    2 |    0 |
|    2 |    3 |    1 |
|    2 |    4 |    0 |
+------+------+------+

Теперь, очевидно, это работает только тогда, когда для каждого значения в col1 есть ровно 4 строки записей. Как мне ввести условные операторы, чтобы это работало, когда не совсем 4 строки?

Имеются следующие ограничения:

a) there will always be an even number of rows (2,4,6..) when grouping by values in `col1`
b) there will be a minimum of 2 rows when grouping by values in `col1`

РЕДАКТИРОВАТЬ:

I думаю, мне нужно уточнить, что я не просто хочу чередование строк 1 и 0. Например, если бы я использовал эту таблицу вместо ...

+------+------+
| col1 | col2 |
+------+------+
|    1 |    1 |
|    1 |    2 |
|    1 |    3 |
|    1 |    4 |
|    1 |    5 |
|    1 |    6 |
|    1 |    7 |
|    1 |    8 |
|    2 |    1 |
|    2 |    2 |
|    2 |    3 |
|    2 |    4 |
|    2 |    5 |
|    2 |    6 |
|    2 |    7 |
|    2 |    8 |
+------+------+

... тогда я ожидал бы такой результат:

+------+------+------+
| col1 | col2 | col3 |
+------+------+------+
|    1 |    1 |    1 |
|    1 |    2 |    0 |
|    1 |    3 |    0 |
|    1 |    4 |    0 |
|    1 |    5 |    1 |
|    1 |    6 |    0 |
|    1 |    7 |    0 |
|    1 |    8 |    0 |
|    2 |    1 |    1 |
|    2 |    2 |    0 |
|    2 |    3 |    0 |
|    2 |    4 |    0 |
|    2 |    5 |    1 |
|    2 |    6 |    0 |
|    2 |    7 |    0 |
|    2 |    8 |    0 |
+------+------+------+

В исходном примере, который я дал, мы сгруппировали на col1 и увидел, что для каждого раздела было 4 строки. Мы берем половину того, что равно 2, и помечаем каждую 2-ю строку (каждую вторую строку) как true / 1.

В этом втором примере, когда мы сгруппируемся по col1, мы видим, что есть 8 строки для каждого раздела. Разделив это пополам, мы получим 4, поэтому каждая 4-я строка должна быть помечена как true / 1.

Ответы [ 2 ]

2 голосов
/ 27 января 2020

Используйте модуль по арифметике c.

Многие диалекты SQL используют % для модуля:

SELECT col1, col2, 
       ROW_NUMBER() OVER (PARTITION BY col1 ORDER BY col2) % 2 as col3
FROM mytable;

Некоторые используют функцию MOD():

SELECT col1, col2, 
       MOD(ROW_NUMBER() OVER (PARTITION BY col1 ORDER BY col2), 2) as col3
FROM mytable;

РЕДАКТИРОВАТЬ:

Вы не хотите чередовать строки. Вы просто хотите два ряда. Для этого вы все равно можете использовать модуль по модулю c, но с несколько иными логиками c:

SELECT col1, col2, 
       (ROW_NUMBER() OVER (PARTITION BY col1 ORDER BY col2) %
        FLOOR(COUNT(*) OVER (PARTITION BY col1) / 2)
       ) as col3
FROM mytable;
1 голос
/ 27 января 2020

Я просто расширяю ответ Гордона, так как его ответ не даст вам правильного результата -

SELECT col1, col2, 
       (CASE WHEN ROW_NUMBER() OVER (PARTITION BY col1 ORDER BY col2) %
        FLOOR(COUNT(*) OVER (PARTITION BY col1) / 2) = 1 THEN 1 ELSE 0 END 
       ) as col3
FROM mytable;
...