SELECT DISTINCT с двумя столбцами

Мне нужно различать как SenderId, так и RecipientId.

Итак, я сделал это:

SELECT DISTINCT M.SenderId, R.StudentId as RecipientId
FROM Message M (nolock) INNER JOIN Recipient R (nolock) ON M.Id=R.MessageId 
GROUP BY M.SenderId, R.StudentId
HAVING StudentId=1 OR SenderId=1

И это работает, но мне там тоже нужно поле M.Text, но без различного. Поэтому я добавил это:

GROUP BY M.SenderId, R.StudentId, M.Text

Но это не работает.


person Matheus Lima    schedule 15.07.2014    source источник
comment
Может ли быть более одного M.Text для каждого отдельного M.Sender, R.StudentId? Если да, то какой из них вы хотели бы выбрать?   -  person John Hartsock    schedule 16.07.2014
comment
Добавлен тег sql-server из-за ключевого слова (nolock)   -  person a_horse_with_no_name    schedule 16.07.2014
comment
Использование distinct и group by не имеет смысла   -  person a_horse_with_no_name    schedule 16.07.2014
comment
Вам не нужны оба DISTINCT и GROUP BY. Вы также можете использовать WHERE вместо HAVING.   -  person Taryn    schedule 16.07.2014
comment
@djikay Вам не нужно выбирать столбец, чтобы использовать его в группе,   -  person Lamak    schedule 16.07.2014
comment
... но это хорошая практика!   -  person Strawberry    schedule 16.07.2014
comment
Пожалуйста, отредактируйте свой вопрос с примерными данными и желаемыми результатами. Ваше объяснение не проясняет, чего вы действительно хотите.   -  person Gordon Linoff    schedule 16.07.2014
comment
RE: использование столбца в select для использования в группе (Lamak / Strawberry) подтвердило, что вам это не нужно, обсуждайте, что это хорошая практика, однако вы бы утверждали, что хотели бы, то есть, как правило, если вы группируете по вещам, которые вы d хотят увидеть, к какой из этих групп относится каждая строка результата.   -  person JohnLBevan    schedule 22.07.2014


Ответы (2)


Вот некоторые варианты; не уверен в формулировке, которая лучше всего соответствует вашим требованиям, но подозреваю, что...

--selects unique combination of sender, recipient and text
--meaning the combo of 3 is unique, but within that combo values
--in each individual column may be repeated

SELECT DISTINCT M.SenderId
, R.StudentId as RecipientId
, M.Text
FROM Message M (nolock) 
INNER JOIN Recipient R (nolock) ON R.MessageId = M.Id
where StudentId=1 
or SenderId=1

or

--returns all unique combos of SenderId and RecipientId
--along with a single corresponding Text field
--max() is just an arbitrary aggregate function to ensure we only
--get 1 result for M.Text

SELECT M.SenderId
, R.StudentId as RecipientId
, max(M.Text)
FROM Message M (nolock) 
INNER JOIN Recipient R (nolock) ON R.MessageId = M.Id
where StudentId=1 
or SenderId=1
group bu M.SenderId
, R.StudentId 
person JohnLBevan    schedule 15.07.2014
comment
Это не работает, поскольку max(M.Text) получает текст, длина которого больше, чем другие, связанные с этими двумя идентификаторами, а не текст относительно самой последней строки. - person Felipe Skinner; 22.07.2014
comment
@Фелипе Скиннер; он работает в зависимости от требований. Вы имеете в виду второй SQL. Для каждой отдельной комбинации отправитель/получатель будет возвращено одно произвольное (максимальное) значение message.text из тех, которые связаны с этой комбинацией отправителя/получателя. - person JohnLBevan; 22.07.2014
comment
@FelipeSkinner относительно вашего комментария о длине; для этого нет логики - max, примененное к строковому (varchar и т. д.) значению, дает последнее значение при сортировке по алфавиту (т.е. при задании «AAA», «B» оно вернет «B»; при задании «AAA», «A» оно вернет «ААА»). - person JohnLBevan; 22.07.2014
comment
Может быть, это было потому, что я тестировал машину и привет, поэтому я так и предположил. Это было моей ошибкой, так как я предположил, что текст был не произвольным, а самым последним. - person Felipe Skinner; 22.07.2014
comment
Там есть еще одна загвоздка, потому что он может вернуть что-то вроде {1,2}, {2,3}, {2,4}, {3,2}, и эти две пары {2,3} - {3,2} являются то же самое... Любая идея, как мы могли бы это решить? Я работаю над этим с несколькими запросами, но я хотел бы знать, есть ли другой способ - person Felipe Skinner; 22.07.2014
comment
@FelipeSkinner в приведенном выше случае {2,3} и {3,2} различны, поскольку они относятся к отправителю и получателю; то есть разные сущности. Если вместо этого они оба были, скажем, messageParticipants, вы могли бы объяснить это, используя что-то вроде следующего: sqlfiddle .com/#!6/d41d8/20409 - однако это будет другой вопрос, чем указанный выше, поэтому его следует задать здесь как новый вопрос. - person JohnLBevan; 22.07.2014

Если я правильно понял ваш вопрос, это сгруппирует то, что вы хотите, и отдельные SenderId и StudentId:

SELECT M.SenderId, R.StudentId as RecipientId, M.Text
FROM Message M (nolock) INNER JOIN Recipient R (nolock) ON M.Id=R.MessageId 
GROUP BY M.SenderId, R.StudentId, M.Text
HAVING COUNT(StudentId) = 1 OR COUNT(SenderId) = 1
person Thomas Veil    schedule 15.07.2014