Make AVG() ignore 0's? [duplicate] - sql

This question already has answers here:
Get AVG ignoring Null or Zero values
(6 answers)
Closed 6 years ago.
I have a column where I can get 0 values, but I need to calculate the average of that column without counting those 0's as part of the divider.
I have the following query:
SELECT AVG(CAST(RATING AS NUMERIC(18, 2))) AS AVERAGE,
QUESTIONID,
Questions.SHORTVERSION,
COUNT(CASE
WHEN RATING > 0
THEN 1
ELSE NULL
END) AS COUNT
FROM AnswersRating
INNER JOIN Questions ON Questions.ID = QUESTIONID
WHERE SURVEYID IN
(
SELECT ID
FROM SURVEYS
WHERE FLIGHTDATAID = '8371'
)
GROUP BY QUESTIONID,
Questions.SHORTVERSION
ORDER BY QUESTIONID;
I read somewhere that I can use NULLIF to help this, but I couldn't figure out how to use it correctly. Anyone who can help me out?

You can use NULLIF to convert your 0s into NULLs as AVG will ignore NULLs:
NULLIF(RATING, 0)

Related

How can I round value to 2 decimal places? [duplicate]

This question already has answers here:
Rounding to 2 decimal places in SQL
(5 answers)
Closed last month.
SELECT
CONCAT((COUNT_PEOPLE_INSIDE_3MILES/ COUNT_TOTAL_PEOPLE*100),'%') Percentage_People_Within_3miles
FROM
(
SELECT count(*) COUNT_PEOPLE_INSIDE_3MILES
FROM CLIENT_DATA
WHERE (ABS(C_ADD_X) >=1 AND ABS(C_ADD_X) <=3) AND (ABS(C_ADD_Y) >=1 AND ABS(C_ADD_Y) <=3)
),
(
SELECT count(CLIENT_ID) COUNT_TOTAL_PEOPLE
FROM CLIENT_DATA
);
You can use the ROUND() function in MySQL To round to 2 decimal.
SELECT ROUND(your_value, 2);
SELECT ROUND(your_value, 2);
This can be done

Can some expert please explain what this query is doing? [duplicate]

This question already has answers here:
Get top 1 row of each group
(19 answers)
Closed 6 months ago.
This is the query in one of the Reports that I am trying to fix. What is being done here?
select
*
from
(
SELECT
[dbo].[RegistrationHistory].[AccountNumber],
[dbo].[RegistrationHistory].[LinkedBP],
[dbo].[RegistrationHistory].[SerialNumber],
[dbo].[RegistrationHistory].[StockCode],
[dbo].[RegistrationHistory].[RegistrationDate],
[dbo].[RegistrationHistory].[CoverExpiry],
[dbo].[RegistrationHistory].[LoggedDate] as 'CoverExpiryNew',
ROW_NUMBER() OVER(PARTITION BY [dbo].[RegistrationHistory].[SerialNumber]
ORDER BY
LoggedDate asc) AS seq,
[dbo].[Registration].[StockCode] as 'CurrentStockCode'
FROM
[SID_Repl].[dbo].[RegistrationHistory]
LEFT JOIN
[SID_Repl].[dbo].[Registration]
on [dbo].[RegistrationHistory].[SerialNumber] = [dbo].[Registration].[SerialNumber]
where
[dbo].[RegistrationHistory].[StockCode] in
(
'E4272HL1',
'E4272HL2',
'E4272HL3',
'E4272H3',
'OP45200HA',
'OP45200HM',
'EOP45200HA',
'EOP45200HM',
'4272HL1',
'4272HL2',
'4272HL3',
'4272H3'
)
)
as t
where
t.seq = 1
and CurrentStockCode in
(
'E4272HL1',
'E4272HL2',
'E4272HL3',
'E4272H3',
'OP45200HA',
'OP45200HM',
'EOP45200HA',
'EOP45200HM',
'4272HL1',
'4272HL2',
'4272HL3',
'4272H3'
)
I am looking for a simplified way of splitting this query into step by step, so that I can see where it is going wrong.
ROW_NUMBER in a subquery combined with a filter on it in the outer query is an idiom to filter out all but the first row in a group. So here
ROW_NUMBER() OVER(PARTITION BY [dbo].[RegistrationHistory].[SerialNumber])
Assigns the row with the lowest SerialNumber 1, the next lowest, 2, etc. Then later
where
t.seq = 1
removes all but the row with the lowest serial number from the result.

Percentage calculation always returns me 0 even that the values are numbers [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
I'm trying to create a percentage for some errors in my table.
I build a query that brings the qty of errors per each value, the total errors, and the division.
But is always giving me 0 (I added a check in order to see if the values are numeric) .
select
ZZ0010 as Error_type
, qty
, total
,running_sum
, isnumeric(total)
,isnumeric(running_sum)
,running_sum/total
from (
select ZZ0010
,(count( [ZZ0010] )) as qty
,sum(nullif(count( [ZZ0010] ),0) ) over(order by count( [ZZ0010] ) desc,ZZ0010) as running_sum
,sum(nullif(count( [ZZ0010] ),0) ) over() as total
from md.CAR_CRM_DS_ZCRM_Z101_BUSINESS_ATTR_VT
group by ZZ0010
having (count( [ZZ0010] )) is not null
) tbl
order by running_sum asc
Error_type
qty
total
running_sum
isnumeric(total)
isnumeric(running_sum)
running_sum/total
2
2123
3931
2123
1
1
0
10
1808
3931
3931
1
1
0
Hmmm . . . I think you can radically simplify this:
select ZZ0010,
count(*) as qty,
sum(count(*)) over (order by count(*) desc) as running_sum,
sum(count(*)) over () as total,
( sum(count(*)) over (order by count(*) desc) * 1.0 /
nullif(sum(count(*)) over (), 0)
) as ratio
from md.CAR_CRM_DS_ZCRM_Z101_BUSINESS_ATTR_VT
group by ZZ0010;
Notes:
I don't know why you would use isnumeric() on number columns.
COUNT() cannot return NULL so the HAVING is redundant.
Use NULLIF() to avoid division by 0. Of course, the sum of counts cannot be zero in your query unless all rows have ZZ0010 as NULL.
SQL Server does integer division. I just multiply by 1.0 to avoid this.
NULLIF(COUNT(), 0) is just really strange. Why distinguish between 0 and NULL in a column that ignores nulls?
I don't think a subquery is particularly useful in this case, but if you don't want to repeat the expressions, you can certainly use a subquery.

What is wrong with the structure of this nested query? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
I am using SQL Server 2014 and I have the following T-SQL query:
SELECT
COUNT (xx.[Email]), xx.[StayID]
FROM
(SELECT
COUNT (x.[RepID]),x.[StayID], x.[Email], x.[RepID]
FROM
(SELECT
*,
([Email] + CONVERT(VARCHAR(10), [Arrival Date], 20)) AS 'RepID'
FROM [Table1]
WHERE [Arrival Date] BETWEEN '2015-07-01' AND '2018-06-30'
AND [Email] <> '') x
GROUP BY
x.[StayID], x.[Email], x.[RepID]
HAVING
COUNT(x.[RepID]) > 1) xx
GROUP BY
xx.[StayID], xx.[Email]
HAVING
COUNT(xx.[Email]) > 1
I am getting the following error message:
No column name was specified for column 1 of 'xx'.
What am I doing wrong here?
I was also looking at changing the query into a CTE. Would that be a solution?
Try this - Modified your query and given the name to xx first column (RepIdCount):
SELECT COUNT (xx.[Email]), xx.[StayID]
FROM (
SELECT COUNT (x.[RepID]) as RepIDCount, x.[StayID], x.[Email], x.[RepID]
FROM (
SELECT *, ([Email] + CONVERT(varchar(10), [Arrival Date], 20)) as 'RepID'
FROM [Table1]
WHERE [Arrival Date] between '2015-07-01' and '2018-06-30'
AND [Email] <> ''
) x
GROUP BY x.[StayID], x.[Email], x.[RepID]
Having Count(x.[RepID]) > 1
) xx
GROUP BY xx.[StayID], xx.[Email]
Having Count(xx.[Email]) > 1
I would say you rewrite the query in a better way, but the issue in your query is in the below line
SELECT COUNT (x.[RepID]), x.[StayID], x.[Email], x.[RepID]
you either remove the COUNT (x.[RepID]) statement since its not used in your parent Select statement or you an give an alias like below
SELECT COUNT (x.[RepID]) as RepCount, x.[StayID], x.[Email], x.[RepID]
If you run this simple query:
select count(*) from some_table
you will notice the result set in the output will have a column name of "No column name".
SQL server does not generate a default column name for aggregate functions.
Thus, the first (and only) column of table xx, i.e.
COUNT (x.[RepID]),x.[StayID], x.[Email], x.[RepID]
has no name. You may not have a subquery that included unnamed columns. give it a name:
COUNT (x.[RepID]) as cnt ,x.[StayID], x.[Email], x.[RepID])
By the way, why go in the trouble of typing all the column names in the COUNT?
Could it be you

How to select distinct rows from a table? [duplicate]

This question already has answers here:
Fetch the rows which have the Max value for a column for each distinct value of another column
(35 answers)
Closed 4 years ago.
I have a table named 'versions' which has columns control_no, revision_id ,revision_dt, version_no, version_dt, created_by, change_type, summary, new_owner.
Each control_no has revision_id ranging from 1 to a specific number. From this table, I want to select
VERSION_NO,CHANGE_TYPE,SUMMARY,CREATED_BY for a CONTROL_NO with max(REVISION_ID).
How to do this?
Use the below query
select VERSION_NO,CHANGE_TYPE,SUMMARY,CREATED_BY from VERSIONS where REVISION_ID in (SELECT A.REVISION_LIST FROM (select max(REVISION_ID) AS REVISION_LIST, CONTROL_NO AS CONT_NO from VERSIONS GROUP BY CONTROL_NO)A);
this will work:
select VERSION_NO,CHANGE_TYPE,SUMMARY,CREATED_BY,max(REVISION_ID),control_no
from versions group by control_no;
By Below Code you can get
SELECT MAX(Version_id) AS Version_id, VERSION_NO,CHANGE_TYPE,SUMMARY,CREATED_By, CONTROL_NO
from table
GROUP BY VERSION_NO,CHANGE_TYPE,SUMMARY,CREATED_By, CONTROL_NO