Why is my output not exactly 2.39? - sql

I need the output with 2 digit like 2.39 but I got the output 2.3980815347721822541966.
That is the problem I don't understand.
Here is my Query.
SELECT M.Description,A.Target,A.Actual,
CASE
WHEN A.Target > 0 THEN A.Actual / CONVERT(DECIMAL(18,2),A.Target)
ELSE 0
END Achievement
FROM (
SELECT * FROM ProcessData PD
WHERE
ProcessYear = 2015 AND ProcessMonth = 1
AND DepotID = 6 AND ModuleID =1
) A
LEFT OUTER JOIN Measure M
ON M.ID = A.MeasureID

You need to format the whole expression rather than just the divisor:
So rather than
THEN A.Actual / CONVERT(DECIMAL(18,2),A.Target)
Change it to:
THEN CONVERT(DECIMAL(18,2), A.Actual / A.Target)
Note that I would expect 2.398 to round to 2.40 (which is what the code I posted will do) - are you sure you want to round down always? If so, look at the ROUND function as well.
THEN CONVERT(DECIMAL(18,2), ROUND(A.Actual / A.Target, 2, 1)

Related

What can I do to update my query to avoid a Division by zero error?

I'm trying to update my query to pull a list of stores if it is marked as "third party" and integrated_images_via_api is set to "true".
When returning these results, I would like to use the divide function to pull averages but i keep running into a division by zero error.
Looks like something went wrong with your query.
net.snowflake.client.jdbc.SnowflakeSQLException: Division by zero
With
menu_data as (
SELECT DISTINCT
dht.date_stamp,
dm.BUSINESS_ID,
ps.provider_type,
dht.MENU_ID,
dht.ACTIVE_STORES_LINKED_TO_MENU,
dht.HAS_HEADER_IMAGE,
dht.HAS_LOGO_IMAGE,
dht.PHOTOS_TOTAL,
dht.NUM_ITEM_IDS,
dht.ITEMS_WITH_DESCRIPTIONS,
dht.PHOTOS_TOTAL*dht.ACTIVE_STORES_LINKED_TO_MENU as sum_photos,
dht.NUM_ITEM_IDS*dht.ACTIVE_STORES_LINKED_TO_MENU as sum_items,
dht.ITEMS_WITH_DESCRIPTIONS*dht.ACTIVE_STORES_LINKED_TO_MENU as sum_desc,
dht.HAS_HEADER_IMAGE*dht.ACTIVE_STORES_LINKED_TO_MENU as sum_headers,
dht.HAS_logo_IMAGE*dht.ACTIVE_STORES_LINKED_TO_MENU as sum_logos,
case when dht.has_header_image AND dht.has_logo_image AND dht.photos_total/dht.NUM_ITEM_IDS >=0.1 --NS, >10% Photos
then 1
else 0 end as NS_Sat
FROM
PRODDB.PUBLIC.DIMENSION_MENU_HEALTH_TRACKING dht
Left Join PRODDB.PUBLIC.DIMENSION_MENU dm ON dm.MENU_ID = dht.MENU_ID
LEFT JOIN DOORDASH_MERCHANT.PUBLIC.MAINDB_STORE_POINT_OF_SALE_INFO ps on ps.store_id=dm.store_id
LEFT JOIN PRODDB.STATIC.POS_PROVIDER_CLASSIFICATION pc on pc.PROVIDER_TYPE=ps.PROVIDER_TYPE
LEFT JOIN PRODDB.STATIC.MENU_DETAILS pm on pm.PROVIDER_ID=pc.PROVIDER_TYPE
WHERE
1 = 1
AND dht.DATE_STAMP = (SELECT max(date_stamp) from PRODDB.PUBLIC.DIMENSION_MENU_HEALTH_TRACKING)
AND dht.ACTIVE_MENU
AND dht.NUM_ITEM_IDS >0
AND --dm.BUSINESS_ID in ('1026','57396','859','1037567','400712','554309')
pc.DIRECT_OR_3PT= 'Third Party'
AND pm.INTEGRATED_IMAGES_VIA_API= 'TRUE'
)
--Main Query
SELECT
md.DATE_STAMP,
business_id,
sum(ACTIVE_STORES_LINKED_TO_MENU) as total_store_menus,
sum(case when md.NS_SAT = 1 then ACTIVE_STORES_LINKED_TO_MENU else NULL end) as NS_store_menus,
total_store_menus - NS_store_menus as ns_opp,
round(NS_Store_menus / total_store_menus, 4) as NS_Perc,
sum(sum_photos) as total_photos,
sum(sum_items) as total_items,
sum(sum_desc) as total_descriptions,
sum(sum_headers) as total_headers,
round(total_photos / total_items,4) as item_perc,
round(total_descriptions / total_items,4) as desc_perc,
total_items - total_photos as item_opp,
round(total_headers / total_store_menus,4) as perc_headers
from menu_data md
where ns_perc >= 0.95
group by 1,2
order by 1,2 DESC

Out of range integer: infinity

So I'm trying to work through a problem thats a bit hard to explain and I can't expose any of the data I'm working with but what Im trying to get my head around is the error below when running the query below - I've renamed some of the tables / columns for sensitivity issues but the structure should be the same
"Error from Query Engine - Out of range for integer: Infinity"
WITH accounts AS (
SELECT t.user_id
FROM table_a t
WHERE t.type like '%Something%'
),
CTE AS (
SELECT
st.x_user_id,
ad.name as client_name,
sum(case when st.score_type = 'Agility' then st.score_value else 0 end) as score,
st.obs_date,
ROW_NUMBER() OVER (PARTITION BY st.x_user_id,ad.name ORDER BY st.obs_date) AS rn
FROM client_scores st
LEFT JOIN account_details ad on ad.client_id = st.x_user_id
INNER JOIN accounts on st.x_user_id = accounts.user_id
--WHERE st.x_user_id IN (101011115,101012219)
WHERE st.obs_date >= '2020-05-18'
group by 1,2,4
)
SELECT
c1.x_user_id,
c1.client_name,
c1.score,
c1.obs_date,
CAST(COALESCE (((c1.score - c2.score) * 1.0 / c2.score) * 100, 0) AS INT) AS score_diff
FROM CTE c1
LEFT JOIN CTE c2 on c1.x_user_id = c2.x_user_id and c1.client_name = c2.client_name and c1.rn = c2.rn +2
I know the query works for sure because when I get rid of the first CTE and hard code 2 id's into a where clause i commented out it returns the data I want. But I also need it to run based on the 1st CTE which has ~5k unique id's
Here is a sample output if i try with 2 id's:
Based on the above number of row returned per id I would expect it should return 5000 * 3 rows = 150000.
What could be causing the out of range for integer error?
This line is likely your problem:
CAST(COALESCE (((c1.score - c2.score) * 1.0 / c2.score) * 100, 0) AS INT) AS score_diff
When the value of c2.score is 0, 1.0/c2.score will be infinity and will not fit into an integer type that you’re trying to cast it into.
The reason it’s working for the two users in your example is that they don’t have a 0 value for c2.score.
You might be able to fix this by changing to:
CAST(COALESCE (((c1.score - c2.score) * 1.0 / NULLIF(c2.score, 0)) * 100, 0) AS INT) AS score_diff

SQL Server Percent Difference is Greater than Value

I have the following table structures:
table c_alert:
|dynamic|symbol|price_usd|
--------------------------
|5 |BTC |13000 |
table c_current:
|symbol|price_usd|
------------------
|BTC |13600 |
I have this query:
SELECT dbo.c_alert.symbol, dbo.c_alert.price_usd AS alert_price, dbo.c_current.price_usd AS current_price, (dbo.c_current.price_usd - dbo.c_alert.price_usd) * 100.0 / dbo.c_alert.price_usd AS pct_diff, dbo.c_alert.dynamic AS pct
FROM dbo.c_alert INNER JOIN
dbo.c_current
ON dbo.c_alert.symbol = dbo.c_current.symbol AND
dbo.c_alert.dynamic > (dbo.c_current.price_usd - dbo.c_alert.price_usd) * 100.0 / dbo.c_alert.price_usd
Which returns this:
|symbol|alert_price|current_price|pct_diff|dynamic|
-----------------------------------------------
|BTC |13000 |13613.3000 |4.7 |5 |
Not very strong with financial queries...Basically I would like to know when the price difference between alert_price and current_price are equal to or greater than value in the dynamic column as a boolean. So where the difference is equal or greater than 5% show True, else False. That dynamic value (integer) could change for each row in the c_alert table. Hope someone can provide a solution to the query.
Because the same percent difference term is required in multiple places in the query, I might go with using a CTE first, which calculates this term. Then, do a straightforward query on the CTE to get the output you want.
WITH cte AS (
SELECT
t2.symbol,
t2.dynamic,
t2.price_usd AS alert_price,
t1.price_usd AS current_price,
100.0*(t1.price_usd - COALESCE(t2.price_usd, 0.0)) / t2.price_usd AS pct_diff
FROM dbo.c_current t1
LEFT JOIN dbo.c_alert t2
ON t1.symbol = t2.symbol
)
SELECT
symbol,
alert_price,
current_price,
pct_diff,
dynamic,
CASE WHEN pct_diff > dynamic THEN 'TRUE' ELSE 'FALSE' END AS result
FROM cte;
Edit:
The logic seems to be working in the demo below. If you still have issues, then edit the demo and paste the link somewhere as a comment.
Demo
Use table aliases so your query is easier to write and to read. Then just use a case:
SELECT a.symbol, a.price_usd AS alert_price,
c.price_usd AS current_price,
(c.price_usd - a.price_usd) * 100.0 / a.price_usd AS pct_diff,
a.dynamic AS pct,
(case when (a.price_usd - c.price_used) > a.dynamic
then 'true' else 'false'
end) as flag
FROM dbo.c_alert a INNER JOIN
dbo.c_current c
ON a.symbol = c.symbol AND
a.dynamic > (c.price_usd - a.price_usd) * 100.0 / a.price_usd;
SQL Server doesn't have a boolean type, so this uses a string. You can use 0 and 1 instead.

how to limit a sql integer query result to <=1

how to limit an integer query result to 1. a return of 2 to be 1, a return 1 to be 1, and a return of 0.5 to be 0.5 because it is <= 1. i don't want to modify the tables, i just want to modify the results.
This is my exact query.
select ((select "V01" from sports where "UID" = '1') * 1.0 ) /
(select "V01" from master where "BALL" = 'REQUIREMENT') ;
I'm using postgres.
To limit, you'd do something like this:
select
case
when yourNumber >= 1 then 1
else yourNumber
end
...
Then you just apply this concept to your query.
As noted by Wiseguy, you could also do:
select LEAST(yourNumber, 1)
, since this is postgresql.
The first solution will work with any ANSI SQL compatible database.
Update
Applied to your query, I think (if I understood what you want correctly) it would be like this:
select LEAST(1,
((select "V01" from sports where "UID" = '1') * 1.0 ) /
(select "V01" from master where "BALL" = 'REQUIREMENT')
);
use the LEAST function , docs: http://www.postgresql.org/docs/8.3/static/functions-conditional.html. Also, check out GREATEST too
SELECT LEAST(1, <your value>)
EDIT replaced GREATEST with LEAST
try this:
select CASE
WHEN ((select V01 from sports where UID = '1') * 1.0 ) /
(select V01 from master where BALL = 'REQUIREMENT') >= 1
THEN 1
ELSE ((select V01 from sports where UID = '1') * 1.0 ) /
(select V01 from master where BALL = 'REQUIREMENT')
END;

sql work out growth in query

I'm trying to work out the percentage of growth between 2 years but it is returning growth as 0.
SELECT my.finmonth,
my.trnyear,
my.drawofficenum,
my1.ytdty,
ly1.ytdly,
CASE
WHEN my1.ytdty <> 0 THEN ( my1.ytdty - ly1.ytdly ) / ly1.ytdly * 100
ELSE 0
END AS Growth2012
FROM salestymonth my
LEFT JOIN salestyytd my1
ON my.finmonth = my1.finmonth
AND my.trnyear = my1.trnyear
AND my.drawofficenum = my1.drawofficenum
LEFT JOIN saleslyytd ly1
ON my.finmonth = ly1.finmonth
AND my.trnyear = ly1.trnyear
AND my.drawofficenum = ly1.drawofficenum
WHERE my.finmonth = '1'
ORDER BY ytdty DESC
Try 1.00*(my1.YTDTY - ly1.YTDLY) / ly1.YTDLY. If your column types are integers, you won't get non-integer results from dividing unless you force the numerator to be a decimal or float.