Запрос SQL Server LEFT JOIN, SUM и GROUP BY, и я в тупике! - PullRequest
9 голосов
/ 03 мая 2011

Я бью свой мозг против этого

У меня есть 3 таблицы SQL Server 2005

userawards

id, awardamount, userid, dateawarded, awardtypeid 

Пользователь:

id, firstname, lastname

Типы премий:

id, title

Так что, если в таблице awards есть строки

1, 300.00, 3, 01-01-2011, 1
2, 125.00, 3, 01-05-2011, 1
3,  50.00, 2, 01-05-2011, 2

строки таблицы пользователя

1, john, smith
2, mark, smith
3, bob, smith

типы наград

1, cash
2, prize

и я хочу, чтобы вывод выглядел примерно так

bob smith, 425.00, cash
mark smith, 50, prize

и т. Д. И т. Д.

Пользователь может иметь несколько наград, результаты должны отображать уникальные пользователи, но с общей суммой наград. кроме того, должно быть 2 объединения, одно, чтобы получить имя / фамилию пользователя, которая находится в таблице пользователя, и название типа вознаграждения.

Итак, мой запрос выглядит так (я знаю, что он не работает)

SELECT id, userid, awardtypeid, SUM(awardamount) 
FROM awards a
LEFT JOIN userinfo ui ON ui.userid = a,userid
LEFT JOIN awardtypes ON awardtypesid = a.awardtypeid
GROUP BY userid

Это вообще возможно?

Ответы [ 4 ]

18 голосов
/ 03 мая 2011

Вы, вероятно, хотите

SELECT userid, 
       awardtypeid, 
       SUM(awardamount) 
FROM   awards a 
       LEFT JOIN userinfo ui 
         ON ui.userid = a.userid 
       LEFT JOIN awardtypes 
         ON awardtypesid = a.awardtypeid 
GROUP  BY userid, 
          awardtypeid 

или

SELECT userid, 
       SUM(awardamount) 
FROM   awards a 
       LEFT JOIN userinfo ui 
         ON ui.userid = a.userid 
       LEFT JOIN awardtypes 
         ON awardtypesid = a.awardtypeid 
GROUP  BY userid

Отбрасывается столбец идентификатора (вероятно, не то, что вы хотите сгруппировать)

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

0 голосов
/ 03 мая 2011

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

select 
    usr.FirstName,
    usr.LastName, 
    awd.AwardAmount,
    AwardTypes = (   
        select Title + ','
        from UserAwards uaw
            join AwardTypes awt on
                uaw.AwardTypeId = awt.Id
        where uaw.UserId = usr.id
        for xml path(''))
from [User] usr
    join (
        select UserId, sum(AwardAmount) AwardAmount
        from UserAwards uaw
        group by UserId
    ) awd on
        awd.UserId = usr.Id
0 голосов
/ 03 мая 2011
SELECT
  ui.FirstName
 ,ui.LastName
 ,at.Title AS Award
 ,SUM(a.AwardAmount) AS AwardAmount
FROM Awards a
  INNER JOIN UserInfo ui ON ui.UserId = a.UserId
  INNER JOIN AwardTypes at ON at.AwardTypeId = a.AwardTypeId
GROUP BY ui.FirstName, ui.LastName, at.Title
ORDER BY ui.LastName, ui.FirstName
0 голосов
/ 03 мая 2011

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

SELECT 
     ??.id ,
     a.userid , 
     a.awardtypeid , 
     ab.awardamount ,
     <whateverelse>
FROM 
     (select userid, SUM(awardamount) as awardamount FROM awards GROUP BY userid) AS ab
INNER JOIN awards AS a on ab.userid = a.userid
LEFT JOIN userinfo AS ui  
  ON ui.userid = a.userid
LEFT JOIN awardtypes AS at 
  ON awardtypesid = a.awardtypeid 

Суммируя сумму вознагражденияза каждого пользователя, прежде чем присоединиться к нему, вы сможете получить то, что хотите, без какой-либо группировки.

...