PHP mysql Distinct, загрузить только 1 набор идентификаторов - PullRequest
5 голосов
/ 04 ноября 2011

Я пытаюсь получить данные, где порядок не имеет значения с уникальными идентификаторами. Так что просто мой запрос будет

SELECT DISTINCT id1, id2 FROM messages ORDER BY date

Если у меня есть база данных со следующими данными:

id1 | id2 | date
 5  |  6  |  1/2/2011
 6  |  5  |  1/1/2011

Мне нужно будет только загрузить столбец с самой новой датой, потому что идентификаторы - те же 2 человека. На самом деле мне нужно загрузить идентификаторы, где один из них ваш, поэтому мой настоящий запрос сейчас

SELECT DISTINCT userid_1, userid_2 
  FROM messages 
    WHERE userid_2=$dbid 
    OR userid_1=$dbid 
ORDER BY date

и я получаю результат как [6 5] [5 9] [9 5] [5 15] [5 6] [5 17]

Результаты 2 и 3 одинаковы, а 1 и 5 одинаковы. На самом деле должны быть запрошены только 4 результата. Спасибо!

Ответы [ 2 ]

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

Один из вариантов:

SELECT DISTINCT 
if(userid_1 >= userid_2,userid_1, userid_2) AS 'id1', 
if(userid_1 >= userid_2,userid_2, userid_1) AS 'id2'

FROM messages 
WHERE userid_2=$dbid OR userid_1=$dbid ORDER BY date
  1. Этот запрос показывает два поля для каждой записи.
  2. Первое поле будет userid1, если оно больше или равно userid2, иначе будет показано userid2
  3. Второе поле имеет противоположную логику
  4. Это гарантирует, что два одинаковых набора результатов будут упорядочены одинаково, поэтому DISTINCT будет считать их одинаковыми.
1 голос
/ 04 ноября 2011

Если ваша цель - получить разные пары, вы можете сделать следующее, чтобы получить меньшую из пар всегда в левом столбце, а большую - в правую, таким образом гарантируя, что разные пары работают:

SELECT DISTINCT
(id1 - ( (id1 - id2) + abs(id1 - id2) ) * .5) as first,
(id2 + ( (id1 - id2) + abs(id1 - id2) ) * .5) as second
FROM messages ORDER BY date;

Поскольку пары всегда расположены, нет необходимости в каких-либо функциях сопряжения.

Пример

+------+------+--------+------------+
| id1  | id2  | val    | pair_date  |
+------+------+--------+------------+
|    4 |    5 | test 1 | 2010-12-25 |
|    5 |    4 | test 2 | 2011-10-31 |
|   17 |   50 | test 3 | 2011-07-04 |
|   50 |   17 | test 4 | 2001-01-01 |
+------+------+--------+------------+

Если я выполню этот запрос:

SELECT DISTINCT 
   (id1 - ( (id1 - id2) + abs(id1 - id2) ) * .5) AS first, 
   (id2 + ( (id1 - id2) + abs(id1 - id2) ) * .5) AS second 
   FROM pairs ORDER BY pair_date;

Я получаю:

+-------+--------+
| first | second |
+-------+--------+
|   4.0 |    5.0 |
|  17.0 |   50.0 |
+-------+--------+
2 rows in set (0.00 sec)

Очевидно, что использование логического значения имеет тот же эффект, его легче читать и, вероятно, быстрее, но приведенный выше алгоритм удобен, если вам просто нужно поменять местами два числа, чтобы одна сторона всегда была меньше.

Я не уверен, почему вы получили ошибку. Я запускаю свои тесты прямо из командной строки MySQL ....

...