简体   繁体   中英

SQL Select Rows Between Dynamic Date Range

For every NAME , I want to query data for the CALL_DATE that is less than or equal to the three months from START_DATE . Below is my attempt but I am getting an error.

Query:

SELECT CALLER_NAME AS "NAME", 
       CAST(CREATED AS DATE) AS "CALL_DATE", 
       DURATION, 
       CAST(START_DATE AS DATE) AS "START_DATE"
FROM table1 
GROUP BY NAME
    HAVING CAST(CREATED AS DATE) >= MIN(CAST(START_DATE AS DATE)) AND CAST(CREATED AS DATE) <= DATEADD(MONTH, 3, CAST(START_DATE AS DATE))
ORDER BY AE_NAME, CALL_DATE

Error

Msg 8121, Level 16, State 1, Line 12 Column 'CREATED' is invalid in the HAVING clause because it is not contained in either an aggregate function or the GROUP BY clause.

Msg 8121, Level 16, State 1, Line 12 Column 'START_DATE' is invalid in the HAVING clause because it is not contained in either an aggregate function or the GROUP BY clause.

I understand why I am getting this error but I don't know how to fix this. I'll very much appreciate your help.

You need to group by the original field names, not the alias's. You also need to group everything that is not aggregated.

This should work:

SELECT CALLER_NAME AS "NAME", 
       CAST(CREATED AS DATE) AS "CALL_DATE", 
       DURATION, 
       CAST(START_DATE AS DATE) AS "START_DATE"
FROM table1 
GROUP BY  CALLER_NAME, CREATED, DURATION, START_DATE
    HAVING CAST(CREATED AS DATE) >= MIN(CAST(START_DATE AS DATE)) AND CAST(CREATED AS DATE) <= DATEADD(MONTH, 3, CAST(START_DATE AS DATE))
ORDER BY AE_NAME, CALL_DATE

Add 'CREATED' and 'START_DATE' to the Group By clause.

SELECT CALLER_NAME AS "NAME", 
       CAST(CREATED AS DATE) AS "CALL_DATE", 
       DURATION, 
       CAST(START_DATE AS DATE) AS "START_DATE"
FROM table1 
GROUP BY NAME, CREATED, START_DATE
    HAVING CAST(CREATED AS DATE) >= MIN(CAST(START_DATE AS DATE)) AND CAST(CREATED AS DATE) <= DATEADD(MONTH, 3, CAST(START_DATE AS DATE))
ORDER BY AE_NAME, CALL_DATE

Or use WHERE rather than HAVING

SELECT CALLER_NAME AS "NAME", 
       CAST(CREATED AS DATE) AS "CALL_DATE", 
       DURATION, 
       CAST(START_DATE AS DATE) AS "START_DATE"
FROM table1 
GROUP BY NAME
    WHER CAST(CREATED AS DATE) >= MIN(CAST(START_DATE AS DATE)) AND CAST(CREATED AS DATE) <= DATEADD(MONTH, 3, CAST(START_DATE AS DATE))
ORDER BY AE_NAME, CALL_DATE

I'm afraid you have to fix it by re-writing from scratch. As the error indicates, when you GROUP on a column or more, the only things that can really be in the select are those columns (or expressions) in the GROUP BY clause, or aggregate functions that apply, in this case, to ALL the rows with a given name.

When you select both the NAME and (say) the DURATION, it doesn't think you want the DURATION value that's in the same row as one NAME, but some function (sum, min, max,etc) of all the DURATIONs beside that NAME. You aren't doing that with ANY of the other columns selected, neither the two dates nor the duration.

This is confusing enough that I'm kind of guessing what you do want, which is not really an aggregate report on multiple rows for each NAME. I think you want a row of output for every row with a NAME, but just select rows that where:

1) CREATED is >= the minimum START_DATE in the whole table 2) CREATED is < three months after the START_DATE in that row

The only aggregation needed at all is to find that minimum START_DATE. The easiest-to-read code for that is a subquery. If I've guess right, that code would be (not sure of your SQL variant, I'll attempt to follow that CAST syntax with cut&paste):


SELECT CALLER_NAME AS "NAME", 
       CAST(CREATED AS DATE) AS "CALL_DATE", 
       DURATION, 
       CAST(START_DATE AS DATE) AS "START_DATE"
FROM table1 
WHERE CAST(CREATED AS DATE) >= (SELECT MIN(CAST(START_DATE AS DATE)) FROM table1)
  AND CAST(CREATED AS DATE) <= DATEADD(MONTH, 3, CAST(START_DATE AS DATE));

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