Reputation: 1229
Is there a way to not duplicate the group by clause when it is included in the select?
For example, one can do: Select x,y,z from mytable order by 1,2,3 If the clauses of x,y, and z are long complicated functions, this saves typing and mistakes. However, I am not aware of a typing saver for: Select f(x),g(y),avg(z) from MyTable group by f(x),g(y)
Any ideas?
Larger example:
SELECT DATEADD(HOUR,datepart(hour,inquirydate),cast(cast(inquirydate as date) as datetime)) as dayhour, COUNT(*) as qty, AVG(workms+queuems+0.0) as avgTimeMs FROM datalog WHERE inquirydate>'1/1/2014' GROUP BY DATEADD(HOUR,datepart(hour,inquirydate),cast(cast(inquirydate as date) as datetime))
Notice a large chunk of the above was repeated. When one repeats oneself, they tend to make mistakes.
Upvotes: 0
Views: 53
Reputation: 1
As mentioned, there are few methods: subquery
, CTE
and OUTER APPLY
:
-- Solution #1: subquery
SELECT
h.dayhour,
COUNT(*) as qty,
AVG(workms+queuems+0.0) as avgTimeMs
FROM (
SELECT
DATEADD(HOUR,datepart(hour,inquirydate),cast(cast(inquirydate as date) as datetime)) as dayhour,
workms, queuems
FROM datalog
WHERE inquirydate>'20140101' -- It's better to use a date literal (DDMMYYY for DATETIME, DD-MM-YYYY for DATE) which is independent of DATEFORMAT / LANGUAGE settings
) h -- hours subquery
GROUP BY h.dayhour;
-- Solution #2: Common Table Expression
;WITH CteHours
AS (
SELECT
DATEADD(HOUR,datepart(hour,inquirydate),cast(cast(inquirydate as date) as datetime)) as dayhour,
workms, queuems
FROM datalog
WHERE inquirydate>'20140101'
)
SELECT h.dayhour,
COUNT(*) as qty,
AVG(workms+queuems+0.0) as avgTimeMs
FROM CteHours h -- hours subquery
GROUP BY h.dayhour;
-- Solution #2: OUTER APPLY
SELECT
expr.dayhour,
COUNT(*) as qty,
AVG(workms+queuems+0.0) as avgTimeMs
FROM datalog d
OUTER APPLY (
SELECT DATEADD(HOUR,datepart(hour,d.inquirydate),cast(cast(d.inquirydate as date) as datetime)) as dayhour
) AS expr
WHERE inquirydate>'20140101'
GROUP BY expr.dayhour;
Usually, I use solution #1 and, sometimes (when query is complex), solution #3.
Upvotes: 0
Reputation: 41
1) Use a User defined function if this is a common calculation
OR
2) As Aaron Bertrand suggested wrap it in a subquery
Upvotes: 0