在包含外部引用SQL的聚合表达式中指定了多个列

时间:2014-05-16 16:32:00

标签: sql sql-server tsql

我有以下查询:

SELECT 
    FileNumber, 
    dbo.GetLocalDateTimeFunc(SentDate) AS SentDate 
INTO #tmp1
FROM FileMain f 
JOIN FileActions fa ON f.FileID = fa.FileID
WHERE ActionDefID = 15 AND SentDate IS NOT NULL

SELECT 
    FileNumber, 
    dbo.GetLocalDateTimeFunc(ReceivedDate) AS ReceivedDate 
INTO #tmp2
FROM FileMain f 
JOIN FileActions fa ON f.FileID = fa.FileID
WHERE ActionDefID = 23 AND ReceivedDate IS NOT NULL

SELECT DISTINCT 
    o.Name AS Company, fm.FileNumber, pc.Name as Client, 
    p.State, c.County, t1.SentDate, t2.ReceivedDate,
(SELECT sum(case    
        when dateadd(day, datediff(day, 0, t1.SentDate), 0) = dateadd(day, datediff(day, 0, t2.ReceivedDate), 0) then
            datediff(second, t1.SentDate, t2.ReceivedDate)
        when [DATE] = dateadd(day, datediff(day, 0, t1.SentDate), 0) then
            case    
            when t1.SentDate > [DATE] + begin_time then datediff(second, t1.SentDate, [DATE] + end_time)
            else duration
            end
        when [DATE] = dateadd(day, datediff(day, 0, t2.ReceivedDate), 0) then
            case    
            when t2.ReceivedDate    <  [DATE] + end_time then datediff(second, [DATE] + begin_time, t2.ReceivedDate)
            else duration
            end
        else duration
        end
          ) 
        / 60.0 / 60.0
    FROM F_TABLE_DATE(t1.SentDate, t2.ReceivedDate) d 
    INNER JOIN Unisource_Calendar c ON d.WEEKDAY_NAME_LONG = c.day_name)
FROM Office o
JOIN PartnerCompany pc ON o.OfficeID = pc.OfficeID
JOIN FileMain fm ON o.OfficeID = fm.OfficeID AND pc.PartnerCompanyID = fm.ClientID
JOIN Property p ON p.FileID = fm.FileID
JOIN County c ON p.CountyID = c.CountyID
JOIN FileActions fa ON fm.FileID = fa.FileID
JOIN #tmp1 t1 ON t1.FileNumber = fm.FileNumber
JOIN #tmp2 t2 ON t2.FileNumber = fm.FileNumber
WHERE p.State IN ('AR', 'CA', 'CO', 'DE', 'DC', 'FL', 'GA', 'IL', 'IN', 'IA', 'KS', 'KY', 'LA', 'MD', 'MA', 'MI', 'MN', 'MS', 'MO', 'MT', 'NE', 'NJ', 'NV', 'NH', 'NY', 'NC', 'ND', 'OH', 'OK', 'PA', 'RI', 'SC', 'TN', 'TX', 'VA', 'WV', 'WI')
ORDER BY SentDate, FileNumber DESC

我在子查询中收到以下错误:

  

在包含外部引用的聚合表达式中指定了多个列。如果要聚合的表达式包含外部引用,则该外部引用必须是表达式中引用的唯一列。

有人知道如何解决这个问题吗?

或者,如果有人具有可以计算日期时间差异的功能,同时排除营业时间和周末也会有所帮助。谢谢!

2 个答案:

答案 0 :(得分:0)

我建议您使用CTE来简化代码(枚举所有表分散注释以提供精确的语句)。您还应该将聚合SUM函数作为PARTITION by expression的一部分进行尝试。这可能有助于避免您提到的问题。

答案 1 :(得分:0)

从我可以收集的信息来看,表函数F_Table_Date在两个参数之间每天返回DATE或DATETIME行,而UnisourceCalendar可能是工作日列表(按照您的提及分配假期)。如果是这种情况,并且UnisourceCalendar也返回DATE或DATETIME列,请考虑以下子查询:

SELECT (COUNT(*) * 60*60*24)
  + (
     SELECT COUNT(*)
     FROM UnisourceCalendar
     WHERE [DATE] = CAST(CONVERT(VARCHAR,t1.SentDate+1,112) AS DATETIME)
    )*DATEDIFF(SS,t1.SentDate,CAST(CONVERT(VARCHAR,t1.SentDate+1,112) AS DATETIME))
  + (
     SELECT COUNT(*)
     FROM UnisourceCalendar
     WHERE [DATE] = CAST(CONVERT(VARCHAR,t1.SentDate+1,112) AS DATETIME)
    )*DATEDIFF(SS,CAST(CONVERT(VARCHAR,t2.ReceivedDate,112) AS DATETIME),t2.ReceivedDate)
FROM UnisourceCalendar C
WHERE C.[DATE] > t1.SentDate AND C.[DATE] < t2.ReceivedDate
GROUP BY t1.SentDate, t2.ReceivedDate

在这里玩什么:

  1. 从UnisourceCalendar每个工作日假设1行,任何其他连接都是多余的。
  2. 那就是所需要的一切。
  3. 使用样式112对一个日期进行转换/转换后的日期转换为剥离时间并重新设置为午夜,从而允许我们从发送日期和之前的午夜获取秒到下一个午夜收到的日期,但仅当每个日期都在unisource日历中时(多次计数,如果为0,则不添加秒数,如果为1,则添加额外的秒数。)
  4. 输出假定您将结果除以子查询之外的数小时。
  5. 复杂?当然,但它应该以相对较短的顺序输出您正在寻找的结果。