2009-07-25 3 views
8

В настоящее время я пытаюсь построить несколько сложное заявление о выборе MySQL. Вот то, что я пытаюсь сделать:MySQL Select Statement DISTINCT для нескольких столбцов

У меня есть таблица вроде этого:

data_table 

uniqueID  stringID   subject 
    1    144   "My Subject" 
    2    144   "My Subject - New" 
    3    144   "My Subject - Newest" 
    4    211   "Some other column" 

Bascially, что я хотел бы сделать, это быть в состоянии SELECT/GROUP BY в STRINGID (картина, что stringID) и не дублируется. Кроме того, я бы хотел, чтобы SELECT была последней строкой stringID (которая в приведенном выше примере является uniqueID 3).

Поэтому, если бы я был запрос к базе данных, он будет возвращать следующие (с последней UniqueID в верхней части):

uniqueID stringID subject 
4   211  "Some other column" 
3   144  "My Subject - Newest" //Notice this is the most recent and distinct stringID row, with the proper subject column. 

Я надеюсь, что это имеет смысл. Спасибо, что помогли.

+2

Вы 100% уверены, UniqueID всегда будет самым высоким ID в таблице? Если нет, я предлагаю добавить временную метку для последней. – lexu

+0

У меня на самом деле есть столбец с меткой времени (не включен в мой пример выше). Итак, как я могу использовать колонку с меткой времени? Работает ли MAX с колонкой timestamp? Благодарю. – 2009-07-25 06:57:28

ответ

9

Попробуйте следующее. Это может быть не самым эффективным запрос, но он будет работать:

SELECT uniqueID, stringID, subject 
FROM data_table 
WHERE uniqueID IN 
(
    SELECT MAX(uniqueID) 
    FROM data_table 
    GROUP BY stringID 
) 
ORDER BY uniqueID DESC 
+1

Этот запрос помог больше всего. Кроме того, я заменил «uniqueID» предложением lexu выше, используя временную метку. Большое спасибо за вашу помощь. – 2009-07-25 07:04:41

+2

Я нашел это в поиске решения подобной проблемы. Это хорошее решение, но есть повышение производительности, которое можно использовать, используя временную таблицу вместо подзаголовка. Создайте временную таблицу на основе выбора sub, затем, когда выберете sub в основном запросе, поместите select * из таблицы temp на свое место. В моем наборе данных из 80000+ строк метод подзапроса занял минуты для запуска, а вместо этого вместо таблицы temp потребовалось около 15 секунд. – GordonM

2

Edit: на основе новой информации, предоставленной ОП в комментарии, это было бы предпочтительнее, чтобы полагаться на uniqueID:

select t.uniqueID 
     , t.stringID 
     , t.subject 
     , t.your_timestamp_col 
from data_table t 
     left outer join data_table t2 
     on t.stringID = t2.stringID 
    and 
     t2.your_timestamp_col > t.your_timestamp_col 
where t2.uniqueID is null 

Если, как Lexu упоминает в комментариях, вы уверены, что самое высокая uniqueID значения всегда соответствует новейшей теме, вы можете сделать это:

select t.uniqueID 
     , t.stringID 
     , t.subject 
from data_table t 
     left outer join data_table t2 
     on t.stringID = t2.stringID 
    and 
     t2.uniqueID > t.uniqueID 
where t2.uniqueID is null 

Что в основном означает: верните мне только те записи от data_table, где не существует более высокого значения uniqueID.

+1

Это будет действительно хуже. Подзапрос не использует ни один из столбцов суперзапросов, и поэтому вычисляется только один раз. «Макс» намного быстрее, чем сравнивать каждый идентификатор один за другим. Более того, соединение должно будет применить предложение 'where'. Подзапрос, однако, создаст хеш-таблицу, которая будет использоваться для поиска каждого из идентификаторов. Ergo, только одно сравнение, и нам не нужно проверять столбец после всех сравнений. – Eric

+0

@ Эрик. Ваш аргумент имеет смысл, но [к сожалению, MySQL в настоящее время не работает таким образом] (http: // stackoverflow.com/questions/3417074/why-would-an-in-condition-be-slower-than-in-sql/3417190 # 3417190) –

3
SELECT DISTINCT(a), 
    (SELECT DISTINCT(b)) AS b, 
    (SELECT DISTINCT(c)) AS c 

FROM tblMyTBL 

WHERE... 
Order By... 
Etc. 
0

У меня была подобная ситуация и вы нашли другой запрос. Попробуйте это:

SELECT MAX(uniqueID), stringID, subject 
FROM data_table 
GROUP BY stringID 
+0

При предоставлении кода, который решает проблему, лучше также дать хотя бы краткое объяснение о том, как это работает, чтобы люди не могли мысленно разбирать его по строкам, чтобы понять различия. – Fluffeh

-1
private void LoadAllFamilyMembers(string relationShip) 
     { 
      lbFamilyMembers.SelectedIndexChanged -= new EventHandler(lbFamilyMembers_SelectedIndexChanged); 
      SqlCommand cmd = new SqlCommand("select familymemberid,name from FamilyMembers where relationship = @relationship", con); 
      cmd.Parameters.AddWithValue("@relationship", relationShip); 
      DataTable dt = new DataTable(); 
      SqlDataAdapter adapter = new SqlDataAdapter(cmd); 
      adapter.Fill(dt); 
      lbFamilyMembers.DataSource = dt; 
      lbFamilyMembers.DisplayMember = "name"; 
      lbFamilyMembers.ValueMember = "familymemberid"; 
      lbFamilyMembers.SelectedIndex = -1; 
      lbFamilyMembers.SelectedIndexChanged += new EventHandler(lbFamilyMembers_SelectedIndexChanged); 
     } 
Смежные вопросы