ISNULL Function, replace null with 0 - sql

I am creating standings for the English Premier League. I need to make standings for home and away records. One of the teams has no home losses, therefore SQL counts this as a NULL not a 0. I want to replace the NULL with a 0. I am having trouble getting the desired results.
select ht.Team,
CASE when FTR IS NULL then 0
else count(ht.FTR)
END as LossesHome
Into dbo.HomeLoss
from dbo.HomeTeam ht
where FTR = 'A'
group by ht.Team, ht.FTR
I thought that this would give me the desired results, however, it only returns 19 teams (there are 20).
I have read other questions that use coalesce and isnull functions and tried them as well but I still only get 19 teams returned.
Any help would be appreciated. If anyone needs more information or code please let me know.
Thanks again.

Looks like the problem is in your WHERE clause where you are not including the FTR null value.
select ht.Team,
CASE when FTR IS NULL then 0
else count(ht.FTR)
END as LossesHome
Into dbo.HomeLoss
from dbo.HomeTeam ht
where FTR = 'A' or FTR is null
group by ht.Team

SELECT ISNULL(myColumn, 0 ) FROM myTable

you can use coalesce function:-
select ht.Team,
coalesce(count(ht.FTR) as count_LossesHome,0)
Into dbo.HomeLoss
from dbo.HomeTeam ht
where FTR = 'A'
group by ht.Team

Related

Using SELECT with a display condition

SELECT DISTINCT Invoice.InvNo, Invoice.OrderNo, Part.PartNo,
orders.orddate AS Order_Date, Invoice.InvDate AS Bill_Date,
MiscChg.Descr, MiscChg.RegFee, Invoice.InvAmt,
Orders.ClaimNo, Firm.FirmName AS Ordering_Firm,
**oppatty.attyid(WHERE oppatty.attyfor = 13)**, Location.Name1 AS Location
The bolded section is the part I'm having trouble with. I know what I have isn't right, but it demonstrates what I would like to accomplish. In the oppatty table, there could be several items listed. I want it to only display "AttyID for the entry that has an ATTYFOR = 13".
Hope this make sense, thanks
Jack
You need to add a CASE WHEN to the select statement.
SELECT DISTINCT
Invoice.InvNo,
Invoice.OrderNo,
Part.PartNo,
orders.orddate AS Order_Date,
Invoice.InvDate AS Bill_Date,
MiscChg.Descr,
MiscChg.RegFee,
Invoice.InvAmt,
Orders.ClaimNo,
Firm.FirmName AS Ordering_Firm,
CASE WHEN oppatty.AttyFor = 13
THEN oppatty.AttyId
ELSE '' END AS attyfor,
Location.Name1 AS Location
FROM
.........
This will display the AttyId field when the row's AttyFor field is equal to 13 and show an empty string when it's not.
Your query has no from or where clause and your question is a bit jumbled, but even so, I think I understand what you want to do. Assuming it's acceptable to fill the "AttyID" values with null where "AttyFor" isn't equal to 13, then you could just use a case statement. Try something like this
select
stuff.things,
case
where oppatty.attyfor <> 13 then null
else oppatty.attyid
end as attyid,
stuff.others
from
oppatty
join stuff on oppatty.ID = stuff.ID
If that's not your desired result, and you'd rather entirely exclude rows where "AttyFor" isnt equal to 13, then just use a where clause.
select
stuff.things,
oppatty.attyid,
stuff.others
from
oppatty
join stuff on oppatty.ID = stuff.ID
where
oppatty.attyfor = 13

SELECT statement that only shows rows where there is a NULL in a specific column

I've got an issue I've been racking my brain on this and the code I have makes sense to me but still doesn't work.
Here is the question:
Give me a list of the names of all the unused (potential) caretakers and the names and types of all unclaimed pieces of art (art that does not yet have a caretaker).
Here is how the tables are set up:
CareTakers: CareTakerID, CareTakerName
Donations: DonationID, DonorID, DonatedMoney, ArtName, ArtType, ArtAppraisedPrice, ArtLocationBuilding, ArtLocationRoom, CareTakerID
Donors: DonorID, DonorName, DonorAddress
Here is the code I have:
SELECT
CareTakerName, ArtName, ArtType
FROM
CareTakers
JOIN
Donations ON CareTakers.CareTakerID = Donations.CareTakerID
WHERE
Donations.CareTakerID = ''
Any help would be very much appreciated!
I would suggest two queries for the reasons I noted in my comment on the OP above... However, since you requested one query, the following should get you what you asked for, although the result sets are not depicted side-by-side.
SELECT
CareTakerName, ArtName, ArtType
FROM
CareTakers
LEFT JOIN
Donations ON CareTakers.CareTakerID = Donations.CareTakerID
WHERE
NULLIF(Donations.CareTakerID,'') IS NULL
UNION -- Returns a stacked result set
SELECT
CareTakerName, ArtName, ArtType
FROM
CareTakers
RIGHT JOIN
Donations ON CareTakers.CareTakerID = Donations.CareTakerID
WHERE
NULLIF(CareTakers.CareTakerID,'') IS NULL
If this is not sufficient, I can supply two separate queries as I suggested above.
*EDIT: Included NULLIF with '' criteria to treat blank and NULL equally in the where clause.
Use a LEFT JOIN:
SELECT CareTakerName, ArtName, ArtType
FROM CareTakers
LEFT JOIN Donations ON CareTakers.CareTakerID = Donations.CareTakerID
WHERE Donations.CareTakerID IS NULL
Donations.CareTakerID = '' is not the same as testing for NULL. That's testing for an empty string.
You want
Donations.CareTakerID is NULL
Also note that
Donations.CaretakerID = NULL
will not give you what you want either (a common mistake.)
Firstly, You need to know What is a NULL value. Is it zero, blank space or something else? The answer is: No.
NULL is not a value, it only means that a value wasn't provided when the row was created.
SELECT d.ArtName, d.ArtType
,(SELECT CareTakerName FROM CareTakers c WHERE c.CareTakerID = d.CareTakerID)CareTakerName
FROM Donations d
WHERE ISNULL(d.CareTakerID, 0) = 0
*I like to use a "default" value for a NULL column
More infotmation here: SQL NULL Values

changing positions of sql query results

The title is not claryifying my problem but this is how i could describe it.
I have a query which returns the following result :
and i was wondering if there is a way to reduce the number of lines from three to one having all the three no null values ( 400, 1000 and 21820 in one line ) with banquet as description.
Thank you for reading.
PS: this is just a capture of a part of the query results and there are a lot of duplicated lines. i can post my query if it would be helpful. i'm using some select case there..
EDIT:
THANK YOU guys but i solved that by copying the results of the main query to input of another one and adding distinct and sum clauses
SELECT description, MAX(number1) AS number1, MAX(number2) AS number2)
FROM myTable
GROUP BY description
At last in Oracle, you can use "When"
Eg:
SELECT
DESCRIPTION,
CASE WHEN SUMPRICE1 IS NULL THEN
CASE WHEN SUMPRICE2 IS NULL THEN
CASE WHEN SUMPRICE3 IS NULL THEN
0
ELSE SUMPRICE3 END
ELSE SUMPRICE2 END
ELSE SUMPRICE1 END AS SUMPRICE
FROM MY_TABLE
GROUP BY DESCRIPTION, SUMPRICE
Off course this is useble just if you have a static number of columns.
EDIT: I think I don't get the problem, but, if you don't want to merge the columns, you can use:
SELECT DESCRIPTION,
MAX(SUMPRICE1) AS SUMPRICE1,
MAX(SUMPRICE2) AS SUMPRICE2,
MAX(SUMPRICEN) AS SUMPRICEN
FROM MY_TABLE
GROUP BY DESCRIPTION
Or you can use the case to avoid the null, in the case of any of rows don't have a value:
SELECT DESCRIPTION,
CASE WHEN MAX(SUMPRICE1) IS NULL THEN 0 ELSE WHEN MAX(SUMPRICE1) END AS SUMPRICE1,
CASE WHEN MAX(SUMPRICE2) IS NULL THEN 0 ELSE WHEN MAX(SUMPRICE2) END AS SUMPRICE2,
CASE WHEN MAX(SUMPRICEN) IS NULL THEN 0 ELSE WHEN MAX(SUMPRICEN) END AS SUMPRICEN
FROM MY_TABLE
GROUP BY DESCRIPTION

Why am I geting null when i use max instead of count

I answered the following question question link. But i fount stringe Behaviour.
when i write this
Update product Set [order]= Case when Not Exists (Select * from
product a where a.ProductTypeID =product.ProductTypeID and a.id
<product.ID )
tHEN 1
eLSE
((Select cOUNT([ORDER])+1 from product b where
b.ProductTypeID =product.ProductTypeID and product.ID <product.id)+1)
eND
It works well but when i write ...'
Update product Set [order]= Case when Not Exists (Select * from
product a where a.ProductTypeID =product.ProductTypeID and a.id
<product.ID )
tHEN 1
eLSE
((Select Max([ORDER])+1 from product b where
b.ProductTypeID =product.ProductTypeID and product.ID <product.id)+1)
eND
It's gives null in else situation i dont understand why?Can Anyone Explain this when i missing why its getting null when i use Max.Here is sql fiddle http://sqlfiddle.com/#!3/1e15d/1 where i use count when i use Max it gives null why?
The difference is that count returns zero for an empty result, but max returns null for an empty result.
You have product.ID <product.id in your condition in the subquery, which will always be false as you are comparing a field to itself. That will make the result from the subquery empty.
It should be b.ID <product.id to compare the value in the table in the subquery to a value in the table in the outer query.
So neither query works as intended, but when you use count you don't get a null value from the empty result.
you can try this(for mysql):
select ifnull(max(column), 0) when max() return null, it give you 0.

If Logic in a SQL Statement

What I'm trying to do should be very simple but somehow I can't reach the right answer to my problem.
I've asked something similar in the past but the answer given to me previously no longer fits the requirements.
So here's what's going on - I need to conditionally select values from a table in my database in a different than the usual manner, like so:
Table:
Id int (not null)
ParentId int (not null)
EventOn DateTime (not null)
User int (null)
By the following select:
SELECT RST.* FROM RangeSheetTime RST
WHERE RST.[User] is not null
(in the above case, I take all the rows where the user isn't null)
Select RST.* FROM RangeSheetTime RST
WHERE RST.[User] is null
(in the above case, I take all the rows where the user is null)
So what am I trying to do? I want to build a select statement that when given a condition, such as EventOn < GETDATE(), will retrieve all the rows where the USER isn't null. In case there aren't any rows where USER isn't null, then it should retrieve the rows where it is null, if any.
How can I put this to work?
Note: I can't use if here, otherwise this would be easier.
EDIT:
I'm going to try to explain it the best I can. Imagine I have 3 rows for the same ParentId, 31.
2 of these rows have a column named StartOrEnd set to 1. There's just a difference between them,
for the 1st one, the USER column is null; for the 2nd one, the USER column has the value 90.
The 3rd row has the column StartOrEnd set to 0.
Now, I want to display results no matter the value of startorend. But there's a catch.
For every startorend, if there are more than 1 row and one of them has USER set to null and the others not null,
then only the non null rows for that startorend will display. but in case there are no non null rows for this condition, than the null values will display. I hope I was clear now.
You should look into the CASE...WHEN construct, which is the equivalent of IF...THEN in SQL:
https://web.archive.org/web/1/http://articles.techrepublic%2ecom%2ecom/5100-10878_11-5078041.html
This may work:
SELECT RST.* FROM RangeSheetTime RST
WHERE RST.[User] IS NOT NULL
UNION ALL
SELECT RST.* FROM RangeSheetTime RST
WHERE RST.[User] IS NULL
AND NOT EXISTS (
SELECT Id FROM RangeSheetTime
WHERE [User] IS NOT NULL
)
I have no means of testing this at the moment, so no guarantees.
If using sqlserver, look at the case statement, it might do what you want.
select a,b,
case when c is not null then 'The not null condition'
else 'The null condition
end [C]
from
Table T
where
condition
If using oracle, I think you can use decode.
Cheers.
Hallaghan, Are you asking about retrieval criteria or manipulating/ display of SQL result, if you are asking about manipulating or display of result case would help you else Union looks good to me.
id , parentid User , StartOrEnd
1 , 31, null , 1
2 , 31, 90 , 1
3 , 31, null , 0
and you want to say now, if startorEnd has multiple value for one parent id, you only want to see the row where user is not null , else the row with null user will come.
if it is like this, the answer given by Jeff should work
The final solution to this problem wasn't any easy to get at but after mashing our heads against a wall, me and a team mate got it down. Although every post from this topic helped us, none could really obtain the values we wanted, there were always flaws, but we are very thankful for all the help provided, without it we'd hardly have reached the answer by now.
So the solution is as follows:
select
P.ParentId RangeSheet
,coalesce(max(P.[End]), max(P.Start)) EventOn
,case when isnull(max(P.[End]), 0) = 0 then 1 else 0 end StartOrEnd
from
(
select
RST.ParentId
,case RST.StartOrEnd when 1 then RST.EventOn else null end Start
,case RST.StartOrEnd when 0 then RST.EventOn else null end [End]
from
(
select
coalesce(MAN.ParentId, AUT.ParentId) ParentId
,coalesce(MAN.StartOrEnd, AUT.StartOrEnd) StartOrEnd
,coalesce(max(MAN.CreatedOn), max(AUT.CreatedOn)) CreatedOn
from
(
-- Obter os manuais
select
RST.ParentId
,RST.StartOrEnd
,MAX(RST.CreatedOn) CreatedOn
from RangeSheetTime RST
where RST.[User] is not null
group by RST.ParentId, RST.StartOrEnd
) MAN
full outer join
(
-- Obter os automáticos
select
RST.ParentId
,RST.StartOrEnd
,MAX(RST.CreatedOn) CreatedOn
from RangeSheetTime RST
where RST.[User] is null
group by RST.ParentId, RST.StartOrEnd
) AUT on MAN.ParentId=AUT.ParentId and MAN.StartOrEnd=AUT.StartOrEnd
group by coalesce(MAN.ParentId, AUT.ParentId), coalesce(MAN.StartOrEnd, AUT.StartOrEnd)
) FOJ
inner join RangeSheetTime RST on FOJ.ParentId=RST.ParentId and FOJ.StartOrEnd=RST.StartOrEnd and FOJ.CreatedOn=RST.CreatedOn
) P
group by P.ParentId