Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p><strong>Q:</strong> how to get an alias to use in the GROUP BY clause</p> <p>One approach is to use an inline view. [EDIT] The answer from Remus Rusanu (+1!) gives an example of a Common Table Expression to accomplish the same thing. [/EDIT]</p> <p>The inline view gets you a simple "alias" for the complex expression which you can then reference in a GROUP BY clause in an outer query:</p> <pre><code>select count(d.callid) , d.duration from (select callid , case when callDuration &gt;= 600 then 12 when callDuration &gt;= 540 then 11 when callDuration &gt;= 480 then 10 when callDuration &gt;= 420 then 9 when callDuration &gt;= 360 then 8 when callDuration &gt;= 300 then 7 when callDuration &gt;= 240 then 6 when callDuration &gt;= 180 then 5 when callDuration &gt;= 120 then 4 when callDuration &gt;= 60 then 3 when callDuration &gt;= 30 then 2 when callDuration &gt; 0 then 1 --else null end as duration from callmetatbl where programid = 1001 and callDuration &gt; 0 ) d group by d.duration </code></pre> <p>Let's unpack that.</p> <ul> <li>the inner (indented) query is called and <em>inline view</em> (we given it an alias <code>d</code>)</li> <li>in the outer query, we can reference the alias <code>duration</code> from <code>d</code></li> </ul> <p>That should be sufficient to answer your question. If you're looking for an equivalent replacement expression, the one from <strong>tekBlues</strong> (<strong>+1 !</strong>) is the right answer (it works on the boundary and for non-integers.)</p> <p>With the replacement expression from tekBlues (+1!): </p> <pre><code>select count(d.callid) , d.duration from (select callid , case when callduration &gt;=30 and callduration&lt;600 then floor(callduration/60)+2 when callduration&gt;0 and callduration&lt; 30 then 1 when callduration&gt;=600 then 12 end as duration from callmetatbl where programid = 1001 and callDuration &gt; 0 ) d group by d.duration </code></pre> <p>(This should be sufficient to answer your question.)</p> <hr> <p>[UPDATE:] sample <strong>user defined function</strong> (a replacement for inline CASE expression)</p> <pre><code>CREATE FUNCTION [dev].[udf_duration](@cd FLOAT) RETURNS SMALLINT AS BEGIN DECLARE @bucket SMALLINT SET @bucket = CASE WHEN @cd &gt;= 600 THEN 12 WHEN @cd &gt;= 540 THEN 11 WHEN @cd &gt;= 480 THEN 10 WHEN @cd &gt;= 420 THEN 9 WHEN @cd &gt;= 360 THEN 8 WHEN @cd &gt;= 300 THEN 7 WHEN @cd &gt;= 240 THEN 6 WHEN @cd &gt;= 180 THEN 5 WHEN @cd &gt;= 120 THEN 4 WHEN @cd &gt;= 60 THEN 3 WHEN @cd &gt;= 30 THEN 2 WHEN @cd &gt; 0 THEN 1 --ELSE NULL END RETURN @bucket END select count(callid) , [dev].[udf_duration](callDuration) from callmetatbl where programid = 1001 and callDuration &gt; 0 group by [dev].[udf_duration](callDuration) </code></pre> <p><strong>NOTES:</strong> be aware that the user defined function will add overhead, and (of course) add a dependency on another database object.</p> <p>This example function is equivalent to the original expression. The OP CASE expression doesn't have any gaps, but it does reference each "breakpoint" twice, I prefer to test only the lower bound. (CASE returns when a condition is satisfied. Doing the tests in reverse lets the unhandled case (&lt;=0 or NULL) fall through without test, an <code>ELSE NULL</code> is not necessary, but could be added for completeness.</p> <p><strong>ADDITIONAL DETAILS</strong></p> <p>(Be sure to check the performance and the optimizer plan, to make sure it's the same as (or not significantly worse than) the original. In the past, I've had problems getting predicates pushed into the inline view, doesn't look like it will be a problem in your case.)</p> <p><strong>stored view</strong></p> <p>Note that the <em>inline</em> view could also be stored as view definition in the database. But there's no reason to do that, other than to "hide" the complex expression from your statement.</p> <p><strong>simplifying the complex expression</strong></p> <p>Another way to make a complex expression "simpler" is to use a user defined function. But a user defined function comes with its own set of issues (including degraded performance.)</p> <p><strong>add database "lookup" table</strong></p> <p>Some answers recommend adding a "lookup" table to the database. I don't see that this is really necessary. It could be done of course, and could make sense if you want to be able to derive different values for <code>duration</code> from <code>callDuration</code>, on the fly, <em>without</em> having to modify your query and <em>without</em> having to run any DDL statements (e.g. to alter a view definition, or modify a user defined function). </p> <p>With a join to a "lookup" table, one benefit is that you could make the query return different result sets by just performing DML operations on the "lookup" table.</p> <p>But that same advantage may actually be a drawback as well.</p> <p>Consider carefully if the benefit actually outweighs the downside. Consider the impact that new table will have on unit testing, how to verify the contents of the lookup table are valid and not changed (any overlaps? any gaps?), impact on ongoing maintenance to the code (due to the additional complexity).</p> <p><strong>some BIG assumptions</strong></p> <p>A lot of the answers given here seem to assume that <code>callDuration</code> is an INTEGER datatype. It seems they have overlooked the possibility that it's not an integer, but maybe I missed that nugget in the question.</p> <p>It's fairly simple test case to demonstrate that:</p> <pre><code>callDuration BETWEEN 0 AND 30 </code></pre> <p>is <em>NOT</em> equivalent to</p> <pre><code>callDuration &gt; 0 AND callDuration &lt; 30 </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload