sql выберите отличную пару из двух столбцов - PullRequest
3 голосов
/ 05 ноября 2011

Допустим, у меня есть 2 столбца:

_______________
| id1  |  id2 |
|------|------|
|  1   |   2  |
|  2   |   1  |
|  3   |   4  |
|  4   |   1  |
|  4   |   3  |
|  1   |   4  |
      ...

Если у меня есть строка id1 = 1 и id2 = 2, где-то после нее будет строка, которая будет id1 = 2 и id2 = 1.

Как я могу получить вершину каждой пары (id1, id2)?


Обновление:

Результат из примера должен быть:

row1: 1 | 2
row2: 3 | 4
row3: 4 | 1

Ответы [ 5 ]

2 голосов
/ 05 ноября 2011

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

В этом примере я предполагаю, что seqField уникален по строке

Тогда это выглядит так:*

--drop table #test

 SELECT 1 as seqField, 1 as id1, 2 as id2
 INTO #test
 UNION ALL
 SELECT 2,2,1
 UNION ALL
 SELECT 3,3,4
 UNION ALL
 SELECT 4,4,1
 UNION ALL
 SELECT 5,4,3
 UNION ALL
 SELECT 6,1,4 
 UNION ALL
 SELECT 7,10,20;

WITH norm AS 
( 
   SELECT CASE WHEN id1 > id2 THEN id1 ELSE id2 END as a,
          CASE WHEN id1 < id2 THEN id1 ELSE id2 END as b, * 
   FROM #test
), setList AS
(
  SELECT DISTINCT a, b, min(seqField) as s
  FROM norm
  GROUP BY a, b
)
SELECT #test.* 
FROM #test
JOIN setList ON #test.seqField = setList.s

Это дает

seq id1 id2
1   1   2
3   3   4
4   4   1
7   10  20

Как указывает sqlchan, seqField можно заменить на %%physloc%%, если у вас нет существующего столбца для использования.

0 голосов
/ 05 ноября 2011

В SQL Server 2008 ...

SELECT a.col1,a.col2
FROM answer a 
JOIN answer b ON a.col1 = b.col2 and b.col1 = a.col2
and a.%%physloc%% = (SELECT MIN(c.%%physloc%%) 
                     FROM  answer c WHERE c.col1 = a.col1 and c.col2 = a.col2)
and b.%%physloc%% = (SELECT MIN(c.%%physloc%%) 
                     FROM answer c WHERE c.col1 = b.col1 and c.col2 = b.col2)
ORDER BY CASE 
     WHEN a.col1 > a.col2 
     THEN a.col2 
     ELSE b.col2 
     END

Однако я бы не стал использовать %% physloc %% (слишком международный) - я бы ввел столбец идентификатора rowid, если важен порядок.Для Oracle вы можете использовать ROWID, и вам не нужно беспокоиться о добавлении столбца.

0 голосов
/ 05 ноября 2011

различим на id1 + "|" + id2. например и это просто концепция, я не пробовал сейчас, SELECT DISTINCT(CONCAT(id1,'|',id2)) FROM .... Рекомендация Сефа по группировке будет иметь больше смысла, хотя

0 голосов
/ 05 ноября 2011

Я уверен, что вы можете просто сделать:

SELECT `id1`, `id2`
FROM `table` 
GROUP BY `id1`, `id2`
ORDER BY `id1`, `id2`

хорошо, чтобы обойти (1,2) и (2, 1) от появления:

SELECT `id1`, `id2`
FROM `table`  a
WHERE NOT EXISTS (
    SELECT TOP 1 1 
    FROM `table` b 
    WHERE b.`id1` < b.`id2` AND b.`id1` = a.`id2` AND b.`id2` = a.`id1'
)
ORDER BY `id1`, `id2`

А если вы хотите сохранить порядок, чтобы отображался первый ряд, вам нужно будет использовать ROWID (больше информации: http://www.sqlite.org/autoinc.html)

SELECT id1, id2
FROM `table`  a
WHERE NOT EXISTS (
    SELECT TOP 1 1 
    FROM `table` b 
    WHERE b.ROWID < a.ROWID AND b.id1 = a.id2 AND b.id2 = a.id1
)

Результаты:

row1: 1 | 2
row2: 3 | 4
row3: 4 | 1
0 голосов
/ 05 ноября 2011

Вы можете использовать объединение, чтобы найти совпадающую пару с id1, id2 инвертированным:

select  t2.*
from    YourTable t1
join    YourTable t2
on      t2.id1 = t1.id2
        and t2.id2 = t1.id1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...