Как вернуть первое значение в объединенных таблицах с агрегированными столбцами - PullRequest
2 голосов
/ 07 июня 2011

У меня есть набор таблиц, из которых я хотел бы построить представление, например:

Участник

ID ¦ Name
---¦------
1  ¦ John

Сделка

ID¦ MemberID
--¦-----------
1 ¦    1

TransactionPart

ID ¦ TransactionID ¦ SchemeID ¦ Value
---¦---------------¦----------¦-------
1  ¦       1       ¦    1     ¦  150
2  ¦       1       ¦    2     ¦  50

Схема

ID ¦ EmailAddress
---¦--------------
1  ¦   x@x.com
2  ¦   y@y.com

Типичная строка в представлении будет содержать Имя участника, общую стоимость транзакции и ЛЮБОЙ адрес электронной почты одной из схем, к которым относятся части транзакции.

Например:

Name ¦ TotalValue ¦ Email Address
-----¦------------¦---------------
John ¦    200     ¦    x@x.com

Я привел этот комментарий ниже, но он возвращает 2 отдельные строки, если адреса электронной почты различаются.

SELECT 
   m.Name as Name, SUM(tp.Value) as TotalValue, s.EmailAddress as EmailAddress
FROM 
   Member m INNER JOIN 
   Transaction t ON m.ID = t.MemberID INNER JOIN 
   TransactionPart tp ON tp.TransactionID = t.ID INNER JOIN 
   Scheme s ON s.ID = tp.SchemeID
GROUP BY 
   m.Name, s.EmailAddress

Результат:

Name ¦ TotalValue ¦ Email Address
-----¦------------¦---------------
John ¦    150     ¦    x@x.com
John ¦    50      ¦    y@y.com

Как мне вернуть единственную строку, содержащую один из адресов электронной почты (возможно, только первый найденный) с суммарным значением итога? Возможно ли это, учитывая приведенные примеры?

Заранее спасибо за любые комментарии / ответы!

Ответы [ 3 ]

1 голос
/ 07 июня 2011

Группировка только по m.Name и применение MAX (или MIN) к s.EmailAddress, даст вам один адрес ('max' с алфавитным порядком для строк):

SELECT 
   m.Name as Name,
   SUM(tp.Value) as TotalValue,
   MAX(s.EmailAddress) as EmailAddress
FROM 
   Member m INNER JOIN 
   Transaction t ON m.ID = t.MemberID INNER JOIN 
   TransactionPart tp ON tp.TransactionID = t.ID INNER JOIN 
   Scheme s ON s.ID = tp.SchemeID
GROUP BY 
   m.Name
1 голос
/ 07 июня 2011

У меня нет SQL 2008 передо мной, но вы можете сделать MIN на поле varchar?

SELECT 
   m.Name as Name, SUM(tp.Value) as TotalValue, MIN(s.EmailAddress) as EmailAddress
FROM 
   Member m INNER JOIN 
   Transaction t ON m.ID = t.MemberID INNER JOIN 
   TransactionPart tp ON tp.TransactionID = t.ID INNER JOIN 
   Scheme s ON s.ID = tp.SchemeID
GROUP BY 
   m.Name


Альтернативой является выполнение некоторой логики для SchemeID, а затем использование коррелированного подзапроса для получения адреса электронной почты ...

SELECT 
   m.Name as Name,
   SUM(tp.Value) as TotalValue,
   (SELECT EmailAddress FROM Scheme WHERE ID = MIN(tp.SchemeID)) as EmailAddress
FROM 
   Member m INNER JOIN 
   Transaction t ON m.ID = t.MemberID INNER JOIN 
   TransactionPart tp ON tp.TransactionID = t.ID
GROUP BY 
   m.Name
1 голос
/ 07 июня 2011

Вы были почти там, все, что нужно, это НЕ группа на EmailAddres.

Используйте любую из агрегированных функций для возврата адреса электронной почты . (Я использовал MIN)

Оператор SQL

SELECT   m.Name as Name
         , SUM(tp.Value) as TotalValue
         , MIN(s.EmailAddress) as EmailAddress
FROM     Member m 
         INNER JOIN Transaction t ON m.ID = t.MemberID 
         INNER JOIN TransactionPart tp ON tp.TransactionID = t.ID 
         INNER JOIN Scheme s ON s.ID = tp.SchemeID
GROUP BY 
         m.Name
...