2012-07-02 3 views
7

У меня есть таблица с двумя столбцами:Mysql Выберите взаимные пары записей, без дублей

  1. person_id
  2. person_id, с которым первым полем идентификатор в сотрудничестве

Мне нужно, чтобы выбрать все пары сотрудничества, легко, но в чем проблема: таблица имеет данные: 987 - 102, 103 - 104, 104 - 103, 21 - 102. В результате с такими данными я должен иметь 3 пары сотрудничества 987 - 102, 103-104, 21-102, как вы видите, 103 - 104 и 104 - 103 записи имеют одинаковую логику, как я могу избежать их дублирования. Есть идеи?

Спасибо, и с наилучшими пожеланиями. Антон.

+0

Покажите нам ваши структуры таблицы –

+0

person_id INT (10), QUESTION_ID INT (10) TEXT_ANSWER текст, я думаю, что второй колонные не нужно, потому что в этом вопросе, я использую его в ИНЕКЕ –

ответ

10

Вы можете использовать LEAST() и GREATEST() функции MySQL, наряду с DISTINCT:

SELECT DISTINCT LEAST(a, b), GREATEST(a, b) FROM mytable 
+1

, если у вас есть только пара ' (2,1) 'он выведет его как' (1,2) ' – alfasin

+1

@alfasin: Описание проблемы подразумевает, что они эквивалентны. В противном случае OP должен уточнить, как было решено, какие из '(103,104)' и '(104,103)' должны храниться и которые отбрасываются. – eggyal

+0

@eggyall: вы правы, не указывается, как было определено, что '(103,104)' должно быть возвращено вместо '(104,103)'. Но сохранение некоторых элементов в других «парах» может быть важным в некоторых случаях. В качестве примера, если этот набор результатов (подзапрос) снова соединен с таблицей, чтобы получить другие столбцы из строки. Суть в том, что порядок элементов в паре может быть важен (и нам не говорят, что это не так.) В спецификации дается примерный набор результатов. Ваш запрос возвращает набор результатов, который отличается от спецификации. – spencer7593

3

Если сохранение порядка элементов в каждой «паре» является не важно, увидеть ответ от eggyal. Этот запрос возвращает набор результатов, который немного отличается от указанного вами, возвращает пару 102-987 вместо 987-102. Он также исключает любые «повторяющиеся» пары, которые появляются в таблице.

При сохранении порядка элементов в каждой паре имеет значение, и вы хотите вернуть «меньше - больше», а не «больше - меньше», если присутствуют обе эти «соответствующие» пары, можно использовать что-то вроде этого:

SELECT c.col1, c.col2 
    FROM mytable c 
    LEFT 
    JOIN mytable d ON d.col1 = c.col2 AND d.col2 = c.col1 AND d.col1 <> d.col2 
WHERE (d.col1 IS NULL OR d.col1 > c.col1) 

Чтобы устранить все повторяющиеся пары и пары «соответствия», добавьте предложения GROUP BY или DISTINCT ключевое слово, например,

SELECT c.col1, c.col2 
    FROM mytable c 
    LEFT 
    JOIN mytable d ON d.col1 = c.col2 AND d.col2 = c.col1 AND d.col1 <> d.col2 
WHERE (d.col1 IS NULL OR d.col1 > c.col1) 
GROUP BY c.col1, c.col2 

ПРИМЕЧАНИЯ:

SQL Fiddle здесь: http://sqlfiddle.com/#!2/1d9e7/1 и здесь: http://sqlfiddle.com/#!2/1d9e7/2

Операторы сравнения не нуль-безопасны, они не могут вернуть ResultSet вы хотите когда либо col1 или col2 содержит значение NULL. (Запрос может быть изменен для обработки значений NULL для col1 и/или col2.) Как написано, оба запроса возвращают, например, как (1,NULL), так и (NULL,1), если эти «совпадающие» «пары» находятся в таблице. (Это сводится к вопросу о том, хотите ли вы учитывать значения NULL для соответствия или нет.)

Также обратите внимание, что оба запроса возвратят строки, где col1=col2.

Обратите внимание, что первый запрос НЕ удаляет «повторяющиеся» строки, которые существуют в таблице. То есть, если повторяющаяся «пара», например, (202,101), появится в двух разных строках, тогда оба будут возвращены (если запрос не возвращает хотя бы одну строку с «совпадающей» парой: (101,202).)

Непонятно, какой результат вы хотите вернуть в этих случаях, поэтому первый запрос показывает шаблон для исключения ТОЛЬКО строк (larger,smaller), когда соответствующая пара (smaller,larger) находится в наборе результатов.

Второй запрос исключает ВСЕ дубликаты и пары «соответствия».

Смежные вопросы