2016-05-10 23:27 GMT+02:00 R Smith <rsmith at rsweb.co.za>:

>
>
> 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?


?Better late as never. ;-)

?


> 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)
>

?I liked the second more, but after I really understood the first I liked
that one more. By the way: in both the first ( does not belong there.
?



> 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.


?I do not do it for performance, but readability and maintenance.

?


> 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)
>

?I went for:
CREATE VIEW linkedinRankingPercentage AS
SELECT date
,      rank
,      outOf
,      COALESCE(NULLIF(CAST(prcnt AS int), prcnt) + 1, CAST(prcnt AS int))
AS percentage
FROM (
    SELECT date
    ,      rank
    ,      outOf
    ,      (100.0 * rank / outof) AS prcnt
    FROM   linkedinRanking
);
?



> HTH,
>

?Certainly.

-- 
Cecil Westerhof

Reply via email to