Поиск…
Добавление всех строк, выбранных для каждой строки
SELECT your_columns, COUNT(*) OVER() as Ttl_Rows FROM your_data_set
Я бы | название | Ttl_Rows |
---|---|---|
1 | пример | 5 |
2 | Foo | 5 |
3 | бар | 5 |
4 | Baz | 5 |
5 | quux | 5 |
Вместо того, чтобы использовать два запроса, чтобы получить счет, а затем линию, вы можете использовать агрегат как функцию окна и использовать полный набор результатов в качестве окна.
Это можно использовать в качестве основы для дальнейших вычислений без сложностей дополнительных самостоятельных подключений.
Настройка флага, если другие строки имеют общее свойство
Предположим, у меня есть эти данные:
Элементы таблицы
Я бы | название | тег |
---|---|---|
1 | пример | unique_tag |
2 | Foo | просто |
42 | бар | просто |
3 | Baz | Привет |
51 | quux | Мир |
Я хотел бы получить все эти строки и узнать, используется ли тег другими строками
SELECT id, name, tag, COUNT(*) OVER (PARTITION BY tag) > 1 AS flag FROM items
Результатом будет:
Я бы | название | тег | флаг |
---|---|---|---|
1 | пример | unique_tag | ложный |
2 | Foo | просто | правда |
42 | бар | просто | правда |
3 | Baz | Привет | ложный |
51 | quux | Мир | ложный |
Если ваша база данных не имеет OVER и PARTITION, вы можете использовать ее для получения того же результата:
SELECT id, name, tag, (SELECT COUNT(tag) FROM items B WHERE tag = A.tag) > 1 AS flag FROM items A
Получение общей суммы
Учитывая эти данные:
Дата | количество |
---|---|
2016-03-12 | 200 |
2016-03-11 | -50 |
2016-03-14 | 100 |
2016-03-15 | 100 |
2016-03-10 | -250 |
SELECT date, amount, SUM(amount) OVER (ORDER BY date ASC) AS running
FROM operations
ORDER BY date ASC
дам тебе
Дата | количество | Бег |
---|---|---|
2016-03-10 | -250 | -250 |
2016-03-11 | -50 | -300 |
2016-03-12 | 200 | -100 |
2016-03-14 | 100 | 0 |
2016-03-15 | 100 | -100 |
Получение N последних строк по нескольким группировкам
Учитывая эти данные
Идентификатор пользователя | COMPLETION_DATE |
---|---|
1 | 2016-07-20 |
1 | 2016-07-21 |
2 | 2016-07-20 |
2 | 2016-07-21 |
2 | 2016-07-22 |
;with CTE as
(SELECT *,
ROW_NUMBER() OVER (PARTITION BY User_ID
ORDER BY Completion_Date DESC) Row_Num
FROM Data)
SELECT * FORM CTE WHERE Row_Num <= n
Используя n = 1, вы получите самую последнюю строку на user_id
:
Идентификатор пользователя | COMPLETION_DATE | ROW_NUM |
---|---|---|
1 | 2016-07-21 | 1 |
2 | 2016-07-22 | 1 |
Поиск записей «вне очереди» с использованием функции LAG ()
Учитывая данные выборки:
Я БЫ | СТАТУС | STATUS_TIME | STATUS_BY |
---|---|---|---|
1 | ОДИН | 2016-09-28-19.47.52.501398 | user_1 |
3 | ОДИН | 2016-09-28-19.47.52.501511 | user_2 |
1 | ТРИ | 2016-09-28-19.47.52.501517 | USER_3 |
3 | ДВА | 2016-09-28-19.47.52.501521 | user_2 |
3 | ТРИ | 2016-09-28-19.47.52.501524 | USER_4 |
Элементы, идентифицированные значениями ID
должны перемещаться из STATUS
'ONE' в 'TWO' в 'THREE' последовательно, без пропуска статуса. Проблема заключается в том, чтобы найти пользователей ( STATUS_BY
), которые нарушают правило и переходят с «ONE» на «THREE».
Аналитическая функция LAG()
помогает решить проблему, возвращая для каждой строки значение в предыдущей строке:
SELECT * FROM (
SELECT
t.*,
LAG(status) OVER (PARTITION BY id ORDER BY status_time) AS prev_status
FROM test t
) t1 WHERE status = 'THREE' AND prev_status != 'TWO'
Если ваша база данных не имеет LAG (), вы можете использовать ее для получения того же результата:
SELECT A.id, A.status, B.status as prev_status, A.status_time, B.status_time as prev_status_time
FROM Data A, Data B
WHERE A.id = B.id
AND B.status_time = (SELECT MAX(status_time) FROM Data where status_time < A.status_time and id = A.id)
AND A.status = 'THREE' AND NOT B.status = 'TWO'