【问题标题】:Aggregate query returning multiple rows when I only want one当我只想要一个时,聚合查询返回多行
【发布时间】:2011-04-21 18:28:42
【问题描述】:

这是原始查询

  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

用户 ID 匹配且组名匹配查询名称的位置

这是我用的

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 

【问题讨论】:

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


    【解决方案1】:

    只需对两个查询进行 JOIN:

    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
    

    旧答案,基于以前版本的问题

    您似乎不想选择calltimeintavetimeint,而是选择这些列的总和,并将它们从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、通话时间和平均时间的每个不同组合返回一行”。

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

    【讨论】:

    • @whatsup “31548.330000”和“8”应该从哪里来?您想要最小值(不是原始查询显示的 SUM 吗?
    • 在我开始之前,我开始添加呼叫数据,例如 calltimeint 和 avetimeint,我只收集验证为 8 和 31548.33 的销售数据,因此出于某种原因,呼叫数据正在收集此信息对于每一行,然后添加它
    • @whatsup 如果您看到的数据太高,可能是因为您多次加入行
    • 生病将我的原始查询发布到顶部它返回所有销售数据总和的单行,然后基于 queryname 列应匹配 dbo.agentdailcalls.userid 和 dbo.agentdailcalls.groupname并显示 avetimeint 和 calltimeint
    • 谢谢我看看对不起这已经困扰我几个小时了
    【解决方案2】:

    试试这个:

    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 
    

    【讨论】:

    • 不,我只是在网站上启动它的速度真的很慢。所以我不认为它实际上有什么不同。除了我正在对每个用户的 CalTime 和 AveTimeInt 求和。
    猜你喜欢
    • 1970-01-01
    • 2012-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-22
    • 2018-06-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多