SQL отличный / групповой по комбинации столбцов - PullRequest
0 голосов
/ 14 сентября 2011

Я пытаюсь сделать SQL-выбор для таблицы, основанной на двух столбцах, но не обычным способом, где комбинация значений в обоих столбцах должна быть уникальной;Я хочу выбрать, где значение может появляться только один раз в любом столбце.Учитывая набор данных:

|pkid | fkself | otherData |
|-----+--------+-----------|
|  1  |   4    |   there   |
|  4  |   1    |    will   |
|  3  |   6    |     be    |
|  2  |   5    |    other  |
|  5  |   2    |   data    |
|  6  |   3    |  columns  |

Мне нужно вернуть либо

|pkid | fkself | otherData |
|-----+--------+-----------|
|  1  |   4    |   there   |
|  3  |   6    |     be    |
|  2  |   5    |    other  |

, либо

|pkid | fkself | otherData |
|-----+--------+-----------|
|  4  |   1    |    will   |
|  5  |   2    |   data    |
|  6  |   3    |  columns  |

Единственный способ, которым я могу думать, это объединить`pkid и fkid для того, чтобы строки 1 и 2 соединились с 1,4, но я не уверен, как это сделать, или если это вообще возможно.

Строкибудет иметь другие столбцы данных, но не имеет значения, какую строку я получу, только то, что я получаю каждый идентификатор только один раз, независимо от того, находится ли значение в pkid или fkself.

Ответы [ 3 ]

1 голос
/ 14 сентября 2011

Вы можете использовать least и greatest, чтобы получить наименьшее или наибольшее значение из двух.Это позволяет вам расположить их в правильном порядке, чтобы сгенерировать эти ключи для вас.Вы можете объединить значения, как вы предложили, но в этом решении это не требуется.С плотным_ранком вы можете создать последовательность для каждого из этих вымышленных ключей.Затем вы можете получить первые OtherData из этой последовательности.

select
  pkid,
  fkself,
  otherData
from
  (select
    pkid,
    fkself,
    otherData,
    dense_rank() over (partition by least(pkid, fkself), greatest(pkid, fkself) order by pkid) as rank
  from
    YourTable t)
where
  rank = 1
0 голосов
/ 14 сентября 2011

Единственный способ сделать это - соединить `pkid и fkid, чтобы строки 1 и 2 соединились в 1,4, но я не уверен, как это сделать.или, если это даже возможно.

Вы можете сделать это с помощью оператора CASE в Oracle:

SQL> SELECT * FROM sample
  2  /

      PKID     FKSELF
---------- ----------
         1          4
         4          1
         3          6
         2          5
         5          2
         7          7

6 rows selected.

SQL> l
  1  SELECT DISTINCT *
  2  FROM (
  3  SELECT CASE WHEN pkid <= fkself THEN pkid||','||fkself
  4                                  ELSE fkself||','||pkid
  5         END "JOINED"
  6    FROM sample
  7* )
SQL> /

JOINED
-------------------------------------------------------------------------------
1,4
2,5
3,6
7,7
0 голосов
/ 14 сентября 2011

Ваша идея возможна, и она должна давать желаемые результаты.

SELECT DISTINCT joinedID
FROM (
SELECT min(id) & "," & max(id) as joinedID
FROM (
    SELECT pkid as id, someUniqueValue 
    FROM table 
    UNION ALL 
    SELECT fkself as id, someUniqueValue 
    FROM table)
GROUP BY someUniqueValue )

Это даст вам уникальный список идентификаторов, составленный по вашему усмотрению.Вы можете легко включить другие поля, добавив их в каждый оператор SELECT.Кроме того, someUniqueValue может быть существующим уникальным полем, новым уникальным полем или объединенными pkid и fkself, если эта комбинация уникальна.

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