On 2016/05/10 11:05 PM, Cecil Westerhof wrote:
> 2016-05-10 22:06 GMT+02:00 Darren Duncan <darren at darrenduncan.net>:
>
>> On 2016-05-10 12:03 AM, Cecil Westerhof wrote:
>>
>>> But it looks like that the following is also acceptable:
>>>      ?
>>> CAST(ROUND(100.0 * rank / outOf + 0.4999999) AS int) AS percentage
>>> and it is a lot simpler. So probably I will go for this.
>>>
>> That might seem simpler but on edge cases it would fail.  Having an
>> if-then version is more reliable in general.  Also less ambiguous as ROUND
>> doesn't behave the same everywhere. -- Darren Duncan
>
> ?OK, I am back to my original version. ;-)
>
> But I made a view:
> CREATE VIEW linkedinRankingPercentage AS
> WITH percentage AS (
>      SELECT date
>      ,      rank
>      ,      outOf
>      ,           100.0 * rank / outOf         AS percentage
>      ,      CAST(100.0 * rank / outOf AS int) AS castedPercentage
>      FROM linkedinRanking
> )
> SELECT date
> ,      rank
> ,      outOf
> ,      (CASE WHEN percentage = castedPercentage
>             THEN castedPercentage
>             ELSE castedPercentage + 1
>         END) AS percentage
> FROM percentage
> ;
>
> It is probably not possible, but just to be sure. ;-)
> I like to have linkedinRankingPercentage the same fields as
> linkedinRanking, but with the calculated field percentage added. I now name
> those fields twice in the creating of the view. Can this be done better? In
> the first SELECT I could change the three fields to a *, but I like the
> symmetry more.
>
> Would the view be a lot more expensive as the table, or if I do not need
> the percentage, is it better to use the table instead of the view?
>



Sorry I'm late to this thread, but why not use a proper CEIL function 
inline? Any of the following two will work in all circumstances and are 
simple enough to be done without the view:

(COALESCE(NULLIF(CAST(v AS int),v)+1,CAST(v AS int))

(CAST(v AS int) + CASE CAST(v AS int) WHEN v THEN 0 ELSE 1 END)


Translated to your Query:

SELECT date
,      rank
,      outOf
,      (COALESCE(NULLIF(CAST((100*rank/outof) AS 
int),(100*rank/outof))+1,CAST((100*rank/outof) AS int)) AS percentage
FROM linkedinRanking

OR

SELECT date
,      rank
,      outOf
,      (CAST((100*rank/outof) AS int) + CASE CAST((100*rank/outof) AS int) WHEN 
(100*rank/outof) THEN 0 ELSE 1 END) AS percentage
FROM linkedinRanking


If you'd like to do a view and avoid repeating the calculation, I'd 
suggest a common table expression rather, like this perhaps:

WITH PC(date, rank, outOf, prcnt) AS (
   SELECT date, rank, outOf, (100*rank/outof)
     FROM linkedinRanking)SELECT date, rank, outOf, (COALESCE(NULLIF(CAST(prcnt 
AS 
int),prcnt)+1,CAST(prcnt AS int)) AS percentage
   FROM PC


Although - I doubt this makes a significant improvement in the 
efficiency, if any. Better yet for this kind of thing would be:

SELECT date, rank, outOf, (COALESCE(NULLIF(CAST(prcnt AS 
int),prcnt)+1,CAST(prcnt AS int)) AS percentage
   FROM (SELECT date, rank, outOf, (100*rank/outof) AS prcnt FROM 
linkedinRanking)


HTH,
Ryan

Reply via email to