简体   繁体   中英

mssql invalid column name when using count distinct

I'm stumped... When I added the count distinct and group by statements to my query I get an error telling me that CallTime and Ticketday are invalid column names. How can I accomplish this without having to write this data to a table first and then query it?

select datename(weekday, calllog.RecvdDate) as Ticketday,
CASE WHEN calllog.RecvdTime between '00:00:00' and '01:00:00' THEN '00:00 to 01:00' 
    WHEN calllog.RecvdTime between '01:00:00' and '02:00:00' THEN '01:00 to 02:00' 
    WHEN calllog.RecvdTime between '02:00:00' and '03:00:00' THEN '02:00 to 03:00'
    WHEN calllog.RecvdTime between '03:00:00' and '04:00:00' THEN '03:00 to 04:00'
    WHEN calllog.RecvdTime between '04:00:00' and '05:00:00' THEN '04:00 to 05:00'
    WHEN calllog.RecvdTime between '05:00:00' and '06:00:00' THEN '05:00 to 06:00'
    WHEN calllog.RecvdTime between '06:00:00' and '07:00:00' THEN '06:00 to 07:00'
    WHEN calllog.RecvdTime between '07:00:00' and '08:00:00' THEN '07:00 to 08:00'
    WHEN calllog.RecvdTime between '08:00:00' and '09:00:00' THEN '08:00 to 09:00'
    WHEN calllog.RecvdTime between '09:00:00' and '10:00:00' THEN '09:00 to 10:00'
    WHEN calllog.RecvdTime between '10:00:00' and '11:00:00' THEN '10:00 to 11:00'
    WHEN calllog.RecvdTime between '11:00:00' and '12:00:00' THEN '11:00 to 12:00'
    WHEN calllog.RecvdTime between '12:00:00' and '13:00:00' THEN '12:00 to 13:00'
    WHEN calllog.RecvdTime between '13:00:00' and '14:00:00' THEN '13:00 to 14:00'
    WHEN calllog.RecvdTime between '14:00:00' and '15:00:00' THEN '14:00 to 15:00'
    WHEN calllog.RecvdTime between '15:00:00' and '16:00:00' THEN '15:00 to 16:00'
    WHEN calllog.RecvdTime between '16:00:00' and '17:00:00' THEN '16:00 to 17:00'
    WHEN calllog.RecvdTime between '17:00:00' and '18:00:00' THEN '17:00 to 18:00'
    WHEN calllog.RecvdTime between '18:00:00' and '19:00:00' THEN '18:00 to 19:00'
    WHEN calllog.RecvdTime between '19:00:00' and '20:00:00' THEN '19:00 to 20:00'
    WHEN calllog.RecvdTime between '20:00:00' and '21:00:00' THEN '20:00 to 21:00'
    WHEN calllog.RecvdTime between '21:00:00' and '22:00:00' THEN '21:00 to 22:00'
    WHEN calllog.RecvdTime between '22:00:00' and '23:00:00' THEN '22:00 to 23:00'
    WHEN calllog.RecvdTime between '23:00:00' and '23:59:59' THEN '23:00 to 00:00'
    END as CallTime, count(distinct(CallTime)) as CallCount
from SERVER.xxxx.dbo.view_calllog calllog
where calllog.RecvdDate > '2015-01-01'
and calllog.NameRecvdBy = 'IVR User Account'
and calllog.CallDesc LIKE '%string%'
group by Ticketday, CallTime
order by Ticketday, CallTime

The problem is that when the query is parsed the alias CallTime hasn't been defined when you try to use it in the select statement.

One solution would be to wrap your query in a common table expression (or use it as a derived table) like this:

;WITH cte (Ticketday, CallTime) AS (
    SELECT 
       DATENAME(weekday, calllog.RecvdDate) AS Ticketday,
       CASE 
          WHEN calllog.RecvdTime BETWEEN '00:00:00' AND '01:00:00' THEN '00:00 to 01:00' 
          WHEN calllog.RecvdTime BETWEEN '01:00:00' AND '02:00:00' THEN '01:00 to 02:00' 
          WHEN calllog.RecvdTime BETWEEN '02:00:00' AND '03:00:00' THEN '02:00 to 03:00'
          WHEN calllog.RecvdTime BETWEEN '03:00:00' AND '04:00:00' THEN '03:00 to 04:00'
          WHEN calllog.RecvdTime BETWEEN '04:00:00' AND '05:00:00' THEN '04:00 to 05:00'
          WHEN calllog.RecvdTime BETWEEN '05:00:00' AND '06:00:00' THEN '05:00 to 06:00'
          WHEN calllog.RecvdTime BETWEEN '06:00:00' AND '07:00:00' THEN '06:00 to 07:00'
          WHEN calllog.RecvdTime BETWEEN '07:00:00' AND '08:00:00' THEN '07:00 to 08:00'
          WHEN calllog.RecvdTime BETWEEN '08:00:00' AND '09:00:00' THEN '08:00 to 09:00'
          WHEN calllog.RecvdTime BETWEEN '09:00:00' AND '10:00:00' THEN '09:00 to 10:00'
          WHEN calllog.RecvdTime BETWEEN '10:00:00' AND '11:00:00' THEN '10:00 to 11:00'
          WHEN calllog.RecvdTime BETWEEN '11:00:00' AND '12:00:00' THEN '11:00 to 12:00'
          WHEN calllog.RecvdTime BETWEEN '12:00:00' AND '13:00:00' THEN '12:00 to 13:00'
          WHEN calllog.RecvdTime BETWEEN '13:00:00' AND '14:00:00' THEN '13:00 to 14:00'
          WHEN calllog.RecvdTime BETWEEN '14:00:00' AND '15:00:00' THEN '14:00 to 15:00'
          WHEN calllog.RecvdTime BETWEEN '15:00:00' AND '16:00:00' THEN '15:00 to 16:00'
          WHEN calllog.RecvdTime BETWEEN '16:00:00' AND '17:00:00' THEN '16:00 to 17:00'
          WHEN calllog.RecvdTime BETWEEN '17:00:00' AND '18:00:00' THEN '17:00 to 18:00'
          WHEN calllog.RecvdTime BETWEEN '18:00:00' AND '19:00:00' THEN '18:00 to 19:00'
          WHEN calllog.RecvdTime BETWEEN '19:00:00' AND '20:00:00' THEN '19:00 to 20:00'
          WHEN calllog.RecvdTime BETWEEN '20:00:00' AND '21:00:00' THEN '20:00 to 21:00'
          WHEN calllog.RecvdTime BETWEEN '21:00:00' AND '22:00:00' THEN '21:00 to 22:00'
          WHEN calllog.RecvdTime BETWEEN '22:00:00' AND '23:00:00' THEN '22:00 to 23:00'
          WHEN calllog.RecvdTime BETWEEN '23:00:00' AND '23:59:59' THEN '23:00 to 00:00'
       END AS CallTime
    FROM SERVER.xxxx.dbo.view_calllog calllog
    WHERE calllog.RecvdDate > '2015-01-01'
    AND calllog.NameRecvdBy = 'IVR User Account'
    AND calllog.CallDesc LIKE '%string%'
)
SELECT Ticketday, COUNT(DISTINCT CallTime) AS CallCount 
FROM cte
GROUP BY Ticketday, CallTime
ORDER BY Ticketday, CallTime

Also, distinct is not a function. The proper syntax is count(distinct CallTime) .

You can't put column aliases in your group by; however, you can put expressions in your group by. In this case though it would look very ugly. Something like:

select datename(weekday, calllog.RecvdDate) as Ticketday,
    <<BIG CASE STATEMENT HERE>> as CallTime, 
    count(distinct(CallTime)) as CallCount
from SERVER.xxxx.dbo.view_calllog calllog
where calllog.RecvdDate > '2015-01-01'
    and calllog.NameRecvdBy = 'IVR User Account'
    and calllog.CallDesc LIKE '%string%'
group by datename(weekday, calllog.RecvdDate), <<BIG CASE STATEMENT HERE>>
order by Ticketday, CallTime

Another way would be to use a subquery so you don't have to look at that big case statement twice. :)

select Ticketday, 
    CallTime, 
    count(distinct(CallTime)) as CallCount
from
    (
    select datename(weekday, calllog.RecvdDate) as Ticketday,
    CASE WHEN calllog.RecvdTime between '00:00:00' and '01:00:00' THEN '00:00 to 01:00' 
        WHEN calllog.RecvdTime between '01:00:00' and '02:00:00' THEN '01:00 to 02:00' 
        WHEN calllog.RecvdTime between '02:00:00' and '03:00:00' THEN '02:00 to 03:00'
        WHEN calllog.RecvdTime between '03:00:00' and '04:00:00' THEN '03:00 to 04:00'
        WHEN calllog.RecvdTime between '04:00:00' and '05:00:00' THEN '04:00 to 05:00'
        WHEN calllog.RecvdTime between '05:00:00' and '06:00:00' THEN '05:00 to 06:00'
        WHEN calllog.RecvdTime between '06:00:00' and '07:00:00' THEN '06:00 to 07:00'
        WHEN calllog.RecvdTime between '07:00:00' and '08:00:00' THEN '07:00 to 08:00'
        WHEN calllog.RecvdTime between '08:00:00' and '09:00:00' THEN '08:00 to 09:00'
        WHEN calllog.RecvdTime between '09:00:00' and '10:00:00' THEN '09:00 to 10:00'
        WHEN calllog.RecvdTime between '10:00:00' and '11:00:00' THEN '10:00 to 11:00'
        WHEN calllog.RecvdTime between '11:00:00' and '12:00:00' THEN '11:00 to 12:00'
        WHEN calllog.RecvdTime between '12:00:00' and '13:00:00' THEN '12:00 to 13:00'
        WHEN calllog.RecvdTime between '13:00:00' and '14:00:00' THEN '13:00 to 14:00'
        WHEN calllog.RecvdTime between '14:00:00' and '15:00:00' THEN '14:00 to 15:00'
        WHEN calllog.RecvdTime between '15:00:00' and '16:00:00' THEN '15:00 to 16:00'
        WHEN calllog.RecvdTime between '16:00:00' and '17:00:00' THEN '16:00 to 17:00'
        WHEN calllog.RecvdTime between '17:00:00' and '18:00:00' THEN '17:00 to 18:00'
        WHEN calllog.RecvdTime between '18:00:00' and '19:00:00' THEN '18:00 to 19:00'
        WHEN calllog.RecvdTime between '19:00:00' and '20:00:00' THEN '19:00 to 20:00'
        WHEN calllog.RecvdTime between '20:00:00' and '21:00:00' THEN '20:00 to 21:00'
        WHEN calllog.RecvdTime between '21:00:00' and '22:00:00' THEN '21:00 to 22:00'
        WHEN calllog.RecvdTime between '22:00:00' and '23:00:00' THEN '22:00 to 23:00'
        WHEN calllog.RecvdTime between '23:00:00' and '23:59:59' THEN '23:00 to 00:00'
        END as CallTime
    from SERVER.xxxx.dbo.view_calllog calllog
    where calllog.RecvdDate > '2015-01-01'
    and calllog.NameRecvdBy = 'IVR User Account'
    and calllog.CallDesc LIKE '%string%'
    ) CallData
group by Ticketday, CallTime
order by Ticketday, CallTime

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM