sql - выбор строки, которая сравнивается со значениями в других строках - PullRequest
0 голосов
/ 25 февраля 2019

Моя база данных выглядит примерно так

Value | Date     | parent_id
 y    | 2019-01-01 | 1
 n    | 2019-01-02 | 1
 n    | 2019-01-03 | 1

Я хочу написать запрос, который будет искать строку с parent_id = 1 и value = 'y', а также сравнивать ее с другими строками, имеющими parent_id=1', но проверим, что date больше даты его строки.

Так что в этом случае он ничего не вернет.

Если бы данные были такими:

Value | Date     | parent_id
 y    | 2019-01-04 | 1
 n    | 2019-01-02 | 1
 n    | 2019-01-03 | 1

Тогда бы вернулась первая строка.

Если это что-то значит, я использую SQLite.

Ответы [ 3 ]

0 голосов
/ 25 февраля 2019

С SQLite> = 3.25 просто используйте оконную функцию ROW_NUMBER():

SELECT * FROM (
    SELECT t.*, ROW_NUMBER() OVER(PARTITION BY t.parent_id ORDER BY t.date DESC) rn
    FROM mytable t
) x WHERE rn = 1 AND parent_id = 1 AND value = 'y'

Оконная функция обычно более эффективна, чем коррелированные подзапросы.

Демонстрация на БД Fiddle .


Запрос работает следующим образом.

Сначала он пересекает таблицу и использует ROW_NUMBER() для назначения aa.ранжирование каждой записи в группе записей, имеющих одинаковый parent_id и запись с наибольшим номером date пронумерованным 1.Вы можете запустить подзапрос, чтобы увидеть, что он на самом деле возвращает (он становится более интересным, когда существует более одного parent_id):

SELECT t.*, ROW_NUMBER() OVER(PARTITION BY t.parent_id ORDER BY t.date DESC) rn
FROM mytable t

Затем все, что остается сделать, - это отфильтровать цель.parent_id, выберите запись с номером строки 1 (т. Е. Запись, которая имеет наибольшее значение date для этого parent_id), и убедитесь, что она имеет value = 'y'.

0 голосов
/ 25 февраля 2019

Другой метод просто ищет последнюю строку, чтобы увидеть, соответствует ли она вашим условиям:

select t.*
from (select t.*
      from t
      where t.parent_id = 1
      order by t.date desc
      limit 1
     ) t
where value = 'y';

Это проверяет, что последняя строка с parent_id = 1 имеет значение 'y'.

0 голосов
/ 25 февраля 2019

Вы можете использовать NOT EXISTS:

select * from tablename t
where 
  parent_id = 1 and value = 'y'
  and not exists (
    select 1 from tablename 
    where parent_id = t.parent_id
    and date > t.date
  )

См. Демоверсию .В качестве предложения: поскольку вы используете SQLite , вам следует рассмотреть возможность изменения формата столбца Date на YYYY-MM-DD, чтобы он был сопоставим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...