Helpers - компьютеры, интернет, программирование

PostgreSQL SELECT UNION, показывающий результат каждого отдельного подзапроса

У меня есть запрос, в котором я использую UNION для объединения двух похожих запросов в один, в результатах я хотел бы, чтобы результат первого запроса был перед результатами второго запроса, однако UNION по умолчанию дает смешанные результаты. Это мой исходный запрос:

SELECT users.name, users.last_name
FROM users
WHERE users.name LIKE 'Paulo%'
UNION
SELECT users.name, users.last_name
FROM users
WHERE users.name LIKE '%Paulo%';

Результат:

    name     | last_name 
-------------+-----------
 João Paulo  | Silva   ----> Second subquery
 Paulo       | Roberto ----> First subquery
 Pedro Paulo | Camargo ----> Second subquery

Возможное решение, которое я нашел, состояло в том, чтобы добавить атрибут в подзапрос, где я сообщаю позицию объекта, однако это мешало группировке UNION, вызывая дублирование результатов.

SELECT 1 as position, users.name, users.last_name
FROM users
WHERE users.name LIKE 'Paulo%'
UNION
SELECT 2 as position, users.name, users.last_name
FROM users
WHERE users.name LIKE '%Paulo%'
ORDER BY position;

Результат:

 position |    name     | last_name 
----------+-------------+-----------
        1 | Paulo       | Roberto
        2 | João Paulo  | Silva
        2 | Paulo       | Roberto (Duplicate record)
        2 | Pedro Paulo | Camargo

Теперь мне нужно решение, чтобы игнорировать повторяющиеся записи конечного результата.

29.01.2021

  • См. meta.stackoverflow.com/questions/333952/. И, пожалуйста, помечайте только соответствующие СУБД 29.01.2021
  • UNION работает на уровне набора результатов, а не на уровне строки базы данных. Ваша попытка определить, какой запрос создал строку, приводит к тому, что они не являются дубликатами с точки зрения объединения. Кстати, какая разница, если источник один и тот же. 29.01.2021

Ответы:


1

Ваш конкретный запрос может быть упрощен до

SELECT
    CASE WHEN users.name LIKE 'Paulo%' THEN 1 ELSE 2 END AS position,
    users.name, users.last_name
FROM users
WHERE users.name LIKE '%Paulo%'
ORDER BY position;

Однако, если вам нужно работать с более общим запросом, вы можете использовать distinct on () пункт:

SELECT DISTINCT ON (name, last_name)
    name, last_name, position
FROM (
    SELECT 1 as position, users.name, users.last_name
    FROM users
    WHERE users.name LIKE 'Paulo%'
    UNION ALL
    SELECT 2 as position, users.name, users.last_name
    FROM users
    WHERE users.name LIKE '%Paulo%') AS t
ORDER BY name, last_name, position;
29.01.2021
  • Первый пример сработал отлично, спасибо 29.01.2021

  • 2

    Я буду использовать Postgresql, чтобы ответить на ваш вопрос.

    Чтобы игнорировать повторяющиеся записи конечного результата, вам нужно будет игнорировать результаты первого запроса при получении второго запроса. Можете ли вы использовать для этого Подзапрос.

    Первый пример:

    SELECT users.name, users.last_name 
    FROM users 
    WHERE users.name LIKE 'Paulo%'
    
    UNION
    
    SELECT users.name, users.last_name
    FROM users 
    WHERE users.name LIKE '%Paulo%'
    AND users.id NOT IN ( SELECT id FROM users WHERE users.name LIKE 'Paulo%' )
    

    Другой альтернативой является использование WithQueries для повышения производительности.

    Второй пример:

    WITH query_cache_01 AS (
      SELECT users.id, users.name, users.last_name
      FROM users 
      WHERE users.name LIKE '%Paulo%'
    ), query_cache_02 AS (
      SELECT id, name, last_name
      FROM query_cache_01
      WHERE name LIKE 'Paulo%'
    )
    
    SELECT query_cache_02.name, query_cache_02.last_name 
    FROM query_cache_02
    
    UNION
    
    SELECT query_cache_01.name, query_cache_01.last_name
    FROM query_cache_01 
    WHERE query_cache_01.id NOT IN ( SELECT id FROM query_cache_02 )
    

    Ссылка: https://www.postgresql.org/docs/12/queries-with.html

    29.01.2021
  • Мне нужно было внести всего несколько корректировок, чтобы оба запроса работали. 29.01.2021
  • Сначала ``` ВЫБЕРИТЕ 2 в качестве позиции, user.name, users.last_name FROM users WHERE users.name LIKE '%Paulo%' AND users.id NOT IN (ВЫБЕРИТЕ id ИЗ пользователей WHERE users.name LIKE 'Paulo%') ORDER ПО позиции; ``` 29.01.2021
  • ``` WITH query_cache_01 AS (ВЫБЕРИТЕ 1 позицию AS, users.id, users.name, users.last_name FROM users WHERE users.name LIKE 'Paulo%'), query_cache_02 AS (SELECT 2 AS position, id, name, last_name FROM пользователи ГДЕ имя НРАВИТСЯ '%Paulo%' ) ВЫБЕРИТЕ query_cache_01.* ОТ query_cache_01 ОБЪЕДИНЕНИЕ ВЫБЕРИТЕ query_cache_02.* ОТ query_cache_02 ГДЕ query_cache_02.id НЕ В ( ВЫБЕРИТЕ id ИЗ query_cache_01 ) ORDER BY position; ``` 29.01.2021

  • 3

    вам не нужен СОЮЗ. Каждый результат, который будет возвращен из вашего первого запроса, ТАКЖЕ вернется в ваш второй запрос.

    ОБНОВИТЬ:

    Я хочу показать сначала имена, которые начинаются с термина, а затем имена, в которых есть термин в любом месте.

    SELECT users.name, users.last_name
    FROM users
    WHERE users.name LIKE 'Paulo%'
    order by position('Paulo' in users.name)
    
    29.01.2021
  • Да, но мне нужно, чтобы результаты первого запроса были первыми, то есть я хочу показать сначала имена, которые начинаются с термина, а затем имена, которые где-либо содержат термин 29.01.2021
  • Новые материалы

    Интуитивное понимание тензоров в машинном обучении
    Тензор является важной концепцией во многих научных областях, таких как математика, физика, обработка сигналов и компьютерное зрение, и это лишь некоторые из них. В математике тензор — это..

    Использование машинного обучения для диагностики болезни Альцгеймера, часть 4
    Маркеры семантической согласованности для ранней диагностики болезни Альцгеймера (arXiv) Автор: Давиде Колла , Маттео Дельсанто , Марко Агосто , Бенедетто Витиелло , Даниэле Паоло Радичони..

    Почему объяснимость так важна прямо сейчас?
    По мере того, как системы искусственного интеллекта и инструменты на основе машинного обучения распространяются в нашей повседневной жизни, как практики, так и критики все чаще заявляют о..

    Анимированный математический анализ
    Использование Manim для создания математических анимированных визуализаций Визуализация данных помогает понять скрытые закономерности в данных, которые невозможно визуализировать..

    Создание простого слайдера изображений с помощью JavaScript
    Узнайте, как создать базовый слайдер изображений с помощью HTML, CSS и JavaScript. Введение В этом уроке мы создадим удобный слайдер изображений, используя JavaScript, HTML и CSS. Ползунок..

    Создание базы данных с помощью супергероя «Python»
    В этом посте мы узнаем, как создать «базу данных SQLite с помощью модуля python sqlite3, создав простую функцию входа и регистрации. Готовы ли вы к этому путешествию? Если да , давайте приступим..

    ИИ для чайников: руководство для начинающих по пониманию будущего технологий
    Вы чувствуете, что остались позади в мире ИИ? Не волнуйтесь, вы не одиноки! Со всей этой шумихой вокруг искусственного интеллекта может быть трудно понять, с чего начать. Но не позволяйте сленгу..