当我只需要一行时,聚合查询返回多行

时间:2011-04-21 18:28:42

标签: sql sql-server-2005 stored-procedures

这是原始查询

  SELECT     'MSD-RES-CRUISE' AS QUERYNAME, dbo.BOOKINGS.USERID, SUM(dbo.BOOKINGS.APRICE) AS total, COUNT(dbo.BOOKINGS.USERID) AS TOTAL2 
    FROM         dbo.BOOKINGS INNER JOIN  dbo.TOURS ON dbo.BOOKINGS.TOUR = dbo.TOURS.TOUR INNER JOIN
                  dbo.MAJOR ON dbo.TOURS.MAJOR = dbo.MAJOR.MAJOR 
    WHERE     (dbo.BOOKINGS.BOOKED BETWEEN CONVERT(int, Dateadd(day,2, @startdate)) AND CONVERT(int, Dateadd(day,2, @enddate))) AND (dbo.MAJOR.SDESCR = 'Cruises') AND  
                          (dbo.BOOKINGS.USERID = @USER) AND (dbo.MAJOR.DIVISION = 'A') and dbo.BOOKINGS.STATUS <> 'XL' GROUP BY dbo.BOOKINGS.USERID 

我要加入的查询

 SELECT     calltimeint, avetimeint
    FROM         dbo.agentdailycalls
    where userid = @user and date1 between @startdate and @enddate

其中userid匹配且groupname与查询名称匹配

这是我用的

SELECT     t0.QUERYNAME, t0.USERID, total, TOTAL2, calltimeint, avetimeint 
FROM       (    SELECT     'MSD-RES-CRUISE' AS QUERYNAME, dbo.BOOKINGS.USERID, SUM(dbo.BOOKINGS.APRICE) AS total, COUNT(dbo.BOOKINGS.USERID) AS TOTAL2 
    FROM         dbo.BOOKINGS INNER JOIN  dbo.TOURS ON dbo.BOOKINGS.TOUR = dbo.TOURS.TOUR INNER JOIN
                  dbo.MAJOR ON dbo.TOURS.MAJOR = dbo.MAJOR.MAJOR 
    WHERE     (dbo.BOOKINGS.BOOKED BETWEEN CONVERT(int, Dateadd(day,2, @startdate)) AND CONVERT(int, Dateadd(day,2, @enddate))) AND (dbo.MAJOR.SDESCR = 'Cruises') AND  
                          (dbo.BOOKINGS.USERID = @USER) AND (dbo.MAJOR.DIVISION = 'A') and dbo.BOOKINGS.STATUS <> 'XL' GROUP BY dbo.BOOKINGS.USERID 
) t0 
INNER JOIN (   SELECT     sum(calltimeint) as calltimeint, sum(avetimeint) as avetimeint , userid
    FROM         dbo.agentdailycalls
    where userid = @user and date1 between @startdate and @enddate and GroupName = 'MSD-RES-CRUISE'
 group by userid
) t1         ON t1.userId = t0.USERID 

2 个答案:

答案 0 :(得分:2)

只需对两个查询进行加入:

SELECT     QUERYNAME, USERID, total, TOTAL2, calltimeint, avetimeint
FROM       ('MSD-RES-CRUISE' ... GROUP BY abcfiles.dbo.BOOKINGS.USERID) t0
INNER JOIN (SELECT userid, groupname, calltimeint, avetimeint ... and @enddate) t1
        ON t1.userId = t0.USERID AND t01.groupname = t0.QUERYNAME

OLD ANSWER,基于问题的先前版本

而不是选择calltimeintavetimeint,您似乎想要选择每个列的SUM,并将其从GROUP BY中删除:

SELECT     ... SUM(dbo.agentdailycalls.calltimeint), SUM(dbo.agentdailycalls.avetimeint)
FROM       dbo.BOOKINGS INNER JOIN ...
GROUP BY   dbo.BOOKINGS.USERID

将它们添加到GROUP BY意味着您希望为这些值的每个不同组合添加一行。因此,GROUP BY userid, calltimeint, avetimeint表示“为用户ID,通话时间和平均时间的每个不同组合返回一行”。

你真正的意思(大概是)“为每个用户返回一行”,所以你应该userid中只有GROUP BY

答案 1 :(得分:1)

试试这个:

SELECT     'MSD-RES-CRUISE' AS QUERYNAME
        , abcfiles.dbo.BOOKINGS.USERID
            , SUM(tt.calltime)
            , SUM(tt.aveTimeint)
        , SUM(abcfiles.dbo.BOOKINGS.APRICE) AS total
        , COUNT(abcfiles.dbo.BOOKINGS.USERID) AS TOTAL2 
FROM         abcfiles.dbo.BOOKINGS 
INNER JOIN  abcfiles.dbo.TOURS 
            ON abcfiles.dbo.BOOKINGS.TOUR = abcfiles.dbo.TOURS.TOUR 
INNER JOIN  abcfiles.dbo.MAJOR 
            ON abcfiles.dbo.TOURS.MAJOR = abcfiles.dbo.MAJOR.MAJOR
INNER JOIN         (SELECT 
                     calltime
               , aveTimeint
            FROM 
                    dbo.agentdailycalls adc
            ) tt 
                     ON tt.userid = abcfiles.dbo.BOOKINDS.USERID 
                    AND tt.date1 BETWEEN @startdate AND @endDate***                         
WHERE     (abcfiles.dbo.BOOKINGS.BOOKED BETWEEN CONVERT(int, Dateadd(day,2, @startdate)) AND CONVERT(int, Dateadd(day,2, @enddate))) 
AND (abcfiles.dbo.MAJOR.SDESCR = 'Cruises') 
AND  (abcfiles.dbo.BOOKINGS.USERID = @USER) 
AND (abcfiles.dbo.MAJOR.DIVISION = 'A') 
and abcfiles.dbo.BOOKINGS.STATUS <> 'XL' 
GROUP BY abcfiles.dbo.BOOKINGS.USERID