SQL - как найти уникальные значения из 2 столбцов?

Я использую SQLite и хочу получать только строки со значениями, уникальными для каждой таблицы. Я знаю, как получить значения для каждого столбца, но не могу создать один (совместимый с sqlite) выбор, чтобы получить уникальное значение из обоих столбцов.

Вот пример данных:

col_A col_B 111 777 222 333 222 111 444 333 222 555 333 666 333 777

Моим желаемым результатом из приведенного выше примера были бы строки с уникальными значениями, которые включают только: 444, 555, 666.

col_A col_B 444 333 222 555 333 666

222 не должно быть в результатах, так как оно появляется несколько раз в столбце col_A. 777 не должно быть в результатах, так как оно появляется несколько раз в col_B. Мне нужно только одно вхождение значения либо в col_A, либо в col_B. Уникальное значение для таблицы, а не для столбца.

Как далеко мне удалось зайти:

SELECT * 
    FROM my_table
    WHERE 
        (SELECT col_A as asset from my_table GROUP BY col_A HAVING COUNT(*) = 1
         UNION
        SELECT col_B as asset from my_table GROUP BY col_B HAVING COUNT(*) = 1)
            IN (col_A, col_B)

Я пробовал использовать UNION и несколько других подходов, но не смог добиться желаемого результата.

А как насчет стоимости 111? Он уникален в обоих столбцах. Что, если столбцы имеют разное количество уникальных значений?

Albina 24.12.2022 13:56

Вы написали 222 should not be in results as it appears multiple times in col_A, и все же это входит в ваши результаты.

MatBailie 24.12.2022 17:04

@MatBailie, да, 222 присутствует в моем примере как одно из значений из-за выбора полной строки. Ваш ответ лучший, так как он заметно быстрее других. Я выделил жирным шрифтом значения в примере результата, так как они важны и результат зависит от них. Значения, не выделенные жирным шрифтом, в примерах результатов появляются только из-за полного выбора строки.

AndroidTank 24.12.2022 21:38
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
1
3
94
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Я думаю, вам нужен такой запрос:

;with unqs as (
  select col_c
  from (
    select col_c, count(col_c) cnt
    from (
      select col_A as col_c
      from my_table
      union all
      select col_B as col_c
      from my_table) as t
     group by col_c) as tt
  where cnt = 1
)
select *
from my_table
where col_A in (select col_c from unqs)
   or col_B in (select col_c from unqs);

Скрипт SQL

Чтобы начать фильтрацию с помощью UNION ALL, учитывая ключевое слово, либо будет подходящим вариантом вместе с предложением HAVING для определения различных значений, таких как

WITH t1 AS  
(
 SELECT col
   FROM (SELECT col_A AS col  FROM t UNION ALL
         SELECT col_B         FROM t) AS tt
  GROUP BY col
 HAVING COUNT(*)=1 
)
SELECT t.* 
  FROM t1
  JOIN t
    ON col IN ( col_A , col_B )

Demo

В зависимости от размера таблицы последний предикат соединения может быть довольно медленным (требуется сканирование). Возможно, будет лучше ОБЪЕДИНИТЬ два запроса, одно соединение в столбце A, другое соединение в столбце B, так как тогда индексы могут использоваться для поиска, если каждый столбец индексируется независимо.

MatBailie 24.12.2022 17:10

Хотел пометить этот ответ как принятый, пока не появится лучший. Как упоминалось в комментарии выше, ваше решение работает медленнее при большем количестве строк. Первый запуск занимает 700-800 мс на 2000 строк. Решение Мата делает это за 150 мс.

AndroidTank 24.12.2022 21:40
Ответ принят как подходящий
WITH
  symetric AS
(
  SELECT col_a, col_b, col_a AS lookup FROM t
  UNION ALL
  SELECT col_a, col_b, col_b AS lookup FROM t
)
SELECT
  col_a, col_b
FROM
  symetric   AS t
WHERE
  NOT EXISTS (
    SELECT * 
      FROM symetric
     WHERE lookup          = t.lookup
       AND (col_a, col_b) <> (t.col_a, t.col_b)
  )
ORDER BY
  col_a, col_b

Демо ; https://dbfiddle.uk/9tzUASle

Спасибо. В настоящее время это самое быстрое решение моей проблемы. Как упоминалось в моем сообщении (OP), мне нужны все/несколько столбцов в реальном решении при возврате результата. Поэтому я изменил ваше решение, чтобы получить полный выбор строки из всех 10+ атрибутов.

AndroidTank 24.12.2022 21:44

@AndroidTank Для достижения наилучших результатов вам будет полезен столбец id и убедитесь, что у вас есть индексы на (col_a, id) (col_b, id), ..., (col_j, id), как выделено в демонстрации.

MatBailie 24.12.2022 21:46

Другие вопросы по теме