2016-11-17 1 views
-1

моя цель состоит в том, чтобы вернуть четкий список из «mFrom» и только тянуть последнюю дату «» из таблицы «сообщения» ..Использование Distinct (COL) в SELECT, с более чем один столбец выбран

Table: messages 
id  mFrom  mTo date 
--  -----  --- ---- 
int int  int datetime 

Я пытаюсь использовать этот запрос:

SELECT DISTINCT(mFrom), date FROM messages WHERE mTo = '116' 

Но я получить эти результаты:

mFrom date 
9  | 2016-11-17 00:30:03 
11 | 2016-11-17 12:35:08 
11 | 2016-11-17 12:35:35 

, и я хотел бы видеть этот Рез льзуется вместо этого.

mFrom date 
9  | 2016-11-17 00:30:03 
11 | 2016-11-17 12:35:35 

Любая помощь приветствуется. Пили аналогичные ответы, используя GROUP BY и внутренний SELECT, но у вас возникли проблемы с сопоставимым запросом для моих конкретных полей.

+0

Объясните, почему вы видите две даты для 11 как не «отличные». – shawnt00

+0

Я удалил несовместимые теги базы данных. –

ответ

7

GROUP BY кажется правильным.

SELECT mFrom, MAX(date) as date 
FROM messages 
WHERE mTo = '116' 
GROUP BY mFrom 
-1
11 | 2016-11-17 12:35:08 
11 | 2016-11-17 12:35:35 

вы можете увидеть поле времени даты, время отстоит от нескольких секунд.

Вы можете сделать это,

SELECT DISTINCT(mFrom), cast(date as date) FROM messages WHERE mTo = '116' 

Это удалит время и дать вам

mFrom date 
9 | 2016-11-17 
11 | 2016-11-17 
+1

Это даст отличные комбинации mFrom и даты. OP хочет ТОЛЬКО самое ПОСЛЕДНЕЕ сообщение для каждого mFrom. – aquinas

+0

Тогда нам нужно использовать MAX –

0

Допустим, у вас есть несколько столбцов, которые являются уникальными в игре, например, вам нужно последнее сообщение от mFrom, но вы также хотите mTo. Затем вы должны рассмотреть секционированный номер строки. Для систем, например. sql-сервер, который поддерживает функции Windows, обычно у них будет функция ROW_NUMBER(), которую вы можете использовать. Ниже приведен пример использования Common Table Expression [CTE] и ROW_NUMBER(). Примечание с использованием RANK() или DENSE_RANK() вместо этого позволит связывание.

;WITH cte AS (
    SELECT * 
     ,ROW_NUMBER() OVER (PARTITION BY mFrom ORDER BY Date DESC) as RowNumber 
    FROM 
     Messages 
    WHERE 
     mTo = 116 
) 

SELECT * 
FROM 
    cte 
WHERE 
    RowNumber = 1 

В моей SQL это становится более сложным, и вы можете сделать это с помощью с помощью переменных:

SELECT * 
FROM 
    (
     SELECT 
      m.* 
      ,(@rn:= if(@mFrom = mFrom, @rn + 1, 
       if(@mFrom:=mFrom, 1, 1) 
       )) as RowNumber 
     FROM 
      Messages m 
      CROSS JOIN (SELECT @mFrom:=0, @rn:=0) var 
     WHERE 
      mTo = 116 
    ) t 
WHERE 
    t.RowNumber = 1 

Или в любой системе вы можете использовать GROUP BY технику, которая показывает Gareth и связать его обратно в исходная таблица, или IN или EXISTS, все эти методы возвращают связи, если 2 сообщения mFrom используют один и тот же MAX (дата). вот пример с соединением.

SELECT * 
FROM 
    Messages m 
    INNER JOIN (SELECT mFrom, MAX(date) as date 
      FROM 
       Messages 
      WHERE 
       mTo = 116 
      GROUP BY 
       mFrom) t 
    ON m.mFrom = t.mFrom 
    AND m.date = t.date 
WHERE 
    mTo = 116 
Смежные вопросы