Ответы пользователя по тегу SQL
  • SQL запрос из нескольких ARCHIVE таблиц с общим ORDER BY?

    Sardar
    @Sardar
    Acrhive база это всегда full table scan. Зато они очень быстрые на добавление. Любое выражение ORDER BY на такой таблице это merge sort со сливом во временные файлы кучи данных (по сути построение индекса на лету), а значит долго. UNION ALL не будет будет сортировать несколько выборок сразу, он просто соединяет результаты. С другой стороны, все ваши таблицы содержат данные только одного интервала, а значит все записи таблицы со старшей датой будут старше записей любой другой младшей таблицы. Тогда просто UINION ALL всех таблиц в порядке даты даст вам нужный результат.
    Ответ написан
    Комментировать
  • Как SQL запросом узнать историю изменения данных?

    Sardar
    @Sardar
    SELECT t.id, COUNT(*), SUM(t.ct)
    FROM (SELECT l.id, y.value, COUNT(*) as ct
        FROM links l
        INNER JOIN history_yap y ON l.link_id = y.link_id
        GROUP BY l.id, y.value) t
    GROUP BY t.id
    UNION ALL
    SELECT l.id, -1, -1
    FROM links l
    LEFT JOIN history_yap y ON l.link_id = y.link_id
    WHERE y.id IS NULL;


    Логика почти та же, но во внутреннем запросе мы также считаем сколько всего было записей в links X history_yap. Также добавлен второй запрос на ссылки без каких либо записей в history_yap. В результате имеем таблицу с тремя колонками:
    * link.id - искомое
    * количество уникальных значений. Если -1, то в history_yap для этого links.id не было ни одной записи. Если больше 1, то есть минимум два history_yap для этой ссылки с разными значениями. Если 1, то смотрим на третью колонку.
    * количество строк в links X history_yap для каждого links.id. Если во второй колонке 1 и в третьей колонке 1, то для этого links.id есть всего одна запись history_yap. Все остальные значения игнорируем.

    P.S. ответил новым постом, т.к. в комментариях код не добавить.
    Ответ написан
  • Как SQL запросом узнать историю изменения данных?

    Sardar
    @Sardar
    SELECT t.id, COUNT(*)
    FROM (SELECT l.id, y.value
        FROM links l
        INNER JOIN history_yap y ON l.link_id = y.link_id
        GROUP BY l.id, y.value) t
    GROUP BY t.id
    HAVING COUNT(*) > 1;


    Требуются индексы на link_id для быстрой работы. Логика:
    * выбрать все ссылки и их историю изменений, нас интересуют уникальные значения. Этот внутренний select можно дополнить where, выбирающий строки только с определенного времени.
    * полученную таблицу снова группируем по id, получаем ссылку и количество уникальных значений.
    * дополняем условием "если уникальных значений больше 1", а значит было изменение.

    Запрос видит только изменения с одного значения на другое. Моменты когда ссылка была добавлена в links, а также первую запись истории в history_yap запрос не видит.
    Ответ написан
  • Что выбрать: primary key или unique для уникального foreign key?

    Sardar
    @Sardar
    Лучше UNIQUE. Это позволит иметь отдельный простой точный id для связной таблицы. Это обычно упрощает работу потом, если придется работать со связной таблицей в параллельных запросах вне serialized транзакций. Лишний индекс для int primary key не проблема.
    Ответ написан
    Комментировать