SQL Server, Remove null values in a select case query - sql

The code below generates around 300 rows, but only a small fraction of them has any value in column "Unit=3". The rest have null values, and hence many duplicate values in column "ekod" exists.
Does anyone know how to remove all rows with a null value in the column "unit=3"?
Best regards!
Result:
ekod unit=3
0004 NULL
0114 15
0114 NULL
0114 NULL
0120 NULL
0120 NULL
0120 46
0120 NULL
Code:
select
A.ekod
,case when A.unit='3' then count(*) end AS [Unit=3]
from [Stat_unitdata].[dbo].[XXX_YYY] A
group by a.ekod, a.unit
order by ekod

You can use sum.
select
A.ekod
,sum(case when a.unit='3' then 1 else 0 end) AS [Unit=3]
from [Stat_unitdata].[dbo].[XXX_YYY] A
group by a.ekod
order by ekod

As a note, if you don't care about ekods with zero units:
select a.ekod, count(*) as [Unit=3]
from [Stat_unitdata].[dbo].[XXX_YYY] a
where a.unit = '3'
group by a.ekod
order by a.ekod;
This returns only ekod values that have at least one unit = '3'.

Related

How to update a value in column based on value from other table in SQL server?

I have two tables match_score and match_condition
I want to update table match_condition and set values of innings, first_4, etc.
Here's the example in which I am trying to update table match_condition with innings value from match_score whenever both of them is not matched
UPDATE a
SET a.innings = b.innings
FROM match_condition a
INNER JOIN (SELECT TOP 1 * FROM match_score order by time_stamp desc ) b
ON a.matchid = b.matchid
WHERE a.innings != b.innings
match_score table
matchid time_stamp overs ball run team_score wicket innings
50821 2021-04-22 10:52:58.640 20 6 1 137 0 1
50821 2021-04-22 10:52:58.637 20 5 1 136 0 1
50821 2021-04-22 10:52:58.633 20 4 0 135 1 1
match_condition table
matchid seriesid match_time innings powerplay_over first_50 first_100 first_150 first_200 first_4 first_6 first_wicket
50820 2780 2021-04-19 18:44:12.360 NULL NULL NULL NULL NULL NULL NULL NULL NULL
50821 2780 2021-04-20 10:00:06.827 NULL NULL NULL NULL NULL NULL NULL NULL NULL
I made changes according to answers here , but still its showing 0 row affected
If value innings in match_condition will never be -1 this query will finish your job:
UPDATE
match_condition
SET
match_condition.innings = a.innings
FROM (
SELECT TOP 1 innings, matchid FROM match_score ORDER BY time_stamp DESC) a
WHERE
match_condition.matchid = a.matchid
AND
ISNULL(match_condition.innings, -1) <> a.innings
If you think that value can be somehow -1, just change in ISNULL operator value to sam 'unreal' number.
Here is DB FIDDLE demo
You can do it by using a subquery
UPDATE match_condition
SET match_condition.innings =
(
SELECT
CASE
WHEN match_condition.innings != b.innings THEN match_condition.innings
ELSE b.innings
END
FROM match_score b
WHERE match_condition.matchid = b.matchid
)
The issue with your query would appear to be that != returns not-true if either value is NULL. It is not appropriate.
You could fix your query as written. However, that would only work for one match in the second table. I would instead suggest apply:
UPDATE mc
SET mc.innings = ms.innings
FROM match_condition mc CROSS APPLY
(SELECT TOP 1 ms.*
FROM match_score ms
WHERE ms.matchid = mc.matchid
ORDER BY time_stamp DESC
) ms;
If you wanted to check on the innings value, you could use:
WHERE mc.innings IS NULL
Also note the use of meaningful table aliases. Do not use arbitrary letters for represent tables. Use table abbreviations!

SQL Server column divide with column with null value

I wanted my outcome to be something like below, the initial null value in either hit1 or hit0n1 become 0, and when hit1 divide by 0 then the percentage will become 0%.
Select CONVERT(varchar(10),ISNULL(a6.hit1*100,0)/NULLIF(a7.hit0n1, 0))+ '%'
.........
left join
(select category,hit,COUNT(hit) as hit1 from(Select Category,UpdateTime,due,
Case When UpdateTime < Due Then 1 Else 0 End As hit From FeedbackDetail Where StatusName ='Closed' and FeedbackDatetime>=DATEADD(day,-31, GETDATE())) a where hit = 1
Group by category, hit) a6 On a1.Category = a6.Category
left join
(select category,COUNT(hit) as hit0n1 from ( Select Category,UpdateTime,due,
Case when UpdateTime < Due then 1 else 0 end as hit From FeedbackDetail Where StatusName ='Closed' and FeedbackDatetime>=DATEADD(day,-31, GETDATE()) ) a
Group by category)
a7 on a1.Category = a7.Category
Expected Outcome
hit1 hit0n1 percentage
_____ _______ ____________
5 0 0%
0 0 0%
3 10 33.3%
but my code display this instead :
hit1 hit0n1 percentage
_____ _______ ____________
5 null NULL
6 6 100%
3 10 33.3%
there is null value in hit0n1, i want to elimate the null value and at the same time i want to avoid 0 number.
select hit1 = a6.hit1,
hit0n1 = isnull(a7.hit0n1, a6.hit1),
percentage = CONVERT(varchar(10),
ISNULL(a6.hit1 * 100.0,0) / ISNULL(a7.hit0n1, a6.hit1) ) + '%'
if you wanted the result in 3 decimal places,
use convert() to convert the calculation result to decimal(10,3) before convert to varchar(10)
percentage = CONVERT(varchar(10),
CONVERT(decimal(10,3),
ISNULL(a6.hit1 * 100.0,0) / ISNULL(a7.hit0n1, a6.hit1) )
) + '%'
EDIT : change to handle hit0n1 = 0
select
hit1,
hit0n1 = isnull(hit0n1, hit1),
percentage = CONVERT(varchar(10),
CONVERT(decimal(10,3),
ISNULL(ISNULL(hit1 * 100.0, 0) / NULLIF(ISNULL(hit0n1, hit1), 0), 0) )
) + '%'
EDIT : explanation on the percentage calculation
ISNULL(hit0n1, hit1) returns first non null value. If hit0n1 is null then it will return hit1 value
if hit0n1 is 0, that division will be error cause it is divide by 0. To handle it NULLIF( <expression> , 0) is use to return NULL value if <expression> is 0. And the result of the division will be NULL value
the final ISNULL() is to change the NULL value to 0
When you want to filter something, you can use WHERE or HAVING. As HAVING requires aggregation, I think it will be clearer to use WHERE. As, we do not want to have NULL values in the result, we can use:
WHERE a6.hit1 IS NOT NULL AND NULLIF(a7.hit0n1, 0) IS NOT NULL
We check for 0 only the a7.hit0n1 as 0 divided on something is valid statement.
Also, if you are working with huge amount of data, you can add filtering indexes on your tables, excluding the NULL values.
In place of NULL what do you want to replace then?
If you want to use the same value as first column then may be you can go with ISNULL(hit0n1,hit1)
NULLIF returns NULL if both expressions are equal otherwise it returns expression one which is also a NULL in your case.
Try the following query-:
Select hit1,
case when isnull(hit0n1,hit1)!=0 then isnull(hit0n1,hit1) end as [hit0n1],
cast(round((hit1/(case when isnull(hit0n1,hit1)!=0 then isnull(hit0n1,hit1) end)*100),2) as varchar(100))+'%'
from [YOUR_TABLE_NAME]
SQL Server 2014

Count different values of 0 from a MySQL query

I'm trying to make this query:
SELECT monthPosted,
sector,
COUNT(sumaAbas) as abasNum,
SUM(sumaAbas) as abas,
COUNT(usdAmount) AS totalNum,
SUM(usdAmount) AS total
FROM DatosSpend
WHERE negotiableProcGl='Y'
GROUP BY sector
The problem I'm getting here is that the COUNT(usdAmount) is counting all values also having a 0 in it.
How can I ignore the count of values=0?
Aggregate functions ignore nulls. You could use a case expression to convert 0s to nulls and thus skip them. E.g.:
SELECT monthPosted,
sector,
COUNT(sumaAbas) as abasNum,
SUM(sumaAbas) as abas,
COUNT(CASE usdAmount WHEN 0 THEN NULL ELSE 1 END) AS totalNum,
SUM(usdAmount) AS total
FROM DatosSpend
WHERE negotiableProcGl = 'Y'
GROUP BY sector
You can just simply exclude the 0 values in the WHERE clause:
WHERE negotiableProcGl='Y' AND value != 0
Where value is your column name

Using a case statement to show the count of two types of values in a column

SELECT
qt.name,
CASE
WHEN qr.isfinished = 0 THEN COUNT(qr.resultid)
END AS 'Attempted',
CASE
WHEN qr.isfinished = 1 THEN COUNT(qr.resultid)
END AS 'Completed'
Need it to show attempted and completed values on the same row
Name attempted Completed
--------------------------------
Algebra I 114 NULL
Algebra II 47 NULL
ASVAB 55 NULL
Algebra I NULL 69
Algebra II NULL 55
ASVAB NULL 84
Thank you for the help!
If isfinished is bit, you can't aggregate on it.
And the CASE goes inside the COUNT
SELECT qt.name,
count(Case when qr.isfinished = 0 THEN 1 END) as 'Attempted',
count(Case when qr.isfinished = 1 THEN 1 END) as 'Completed'
FROM
...
GROUP BY
qt.name
There are multiple ways you could do this, for example you could do this with joins, or you can use group by -- like so:
SELECT
qt.name,
SUM(CASE qr.isfinsihed WHEN 1 THEN 1 ELSE 0) AS 'Attempted',
SUM(CASE qr.isfinished WHEN 0 THEN 1 ELSE 0) AS 'Completed'
FROM -- what ever your from clause is, it goes here --
GROUP BY
qt.name
In order to have them on the same row, you will need to group by what they have in common. From what you have given in the question, I am assuming that is the qt.name.
Next, you can use the SUM aggregate to get each field count. All of the records that meet the criteria for each item count towards the sum, the others don't. You can also use count with 1's and Null's, I prefer using Sum because it can allow for weighted totals if I need them.

SQL - How to show in one row the same field with different values from 2 rows

I have a select with a specific 'where' clause where I get 2 rows, but I will need to show in one row these 2 values but with different 'names'
select
case when t_docn <> 0 then t_docd end as doc_date,
case when t_docn = 0 then t_docd end as pay_date
from
ttfacr200606
where
t_ninv = '40000122'
and
t_ccur = 'BRL'
with this code I am getting
doc_date pay_date
NULL 2015-08-21 00:00:00.000
2015-09-18 00:00:00.000 NULL
I will need
doc_date pay_date
2015-09-18 00:00:00.000 2015-08-21 00:00:00.000
Thanks guys!
You can use an aggregation function to do that, although you will need to verify if it will fit for all cases you have. It will be like this:
select
t_ninv,
max(case when t_docn <> 0 then t_docd else null end) as doc_date,
max(case when t_docn = 0 then t_docd else null end) as pay_date
from ttfacr200606
where t_ccur = 'BRL'
and t_ninv = '40000122'
group by t_ninv;
Pay attention that I used a column to be the common point as said in comments, because if you wont use it and with many rows the query result can be unpredictable.