MYSQL database IFNULL query - mysql

I'm trying to display a 'NULL' value as 0 using 'IFNULL' but it returns all rows as null or 0. Everything works fine until I add the 'lounge2' table and the 'lounge2order2' table. The order2.lounge2orderid is 'NULL'. I know it has something to do with 'JOINS' but not sure where or which to implement.
Thanks all...
SELECT orders2.orderid, orders2.orderdate, branch2.branchname, COUNT(orders2.garment2orderid) AS 'no gar orders', SUM(garment2.hireprice) as 'total gar sold',
COUNT(orders2.lounge2orderid+IFNULL(orders2.lounge2orderid,0)) as 'No of lounge sales', SUM(lounge2.hirerate)
from orders2, branch2, garment2, garment2order2, lounge2, lounge2order2
WHERE orders2.orderid IN
(SELECT orders2.orderid FROM orders2
WHERE orders2.branchid = 2
AND YEAR(orders2.orderdate)= 2011)
AND branch2.branchid IN
(SELECT branch2.branchid from branch2
WHERE branch2.branchid = orders2.branchid)
AND garment2order2.garment2orderid IN
(SELECT garment2order2.garment2orderid FROM garment2order2
WHERE garment2order2.garment2orderid = orders2.garment2orderid)
AND garment2.garmentid IN
(SELECT garment2.garmentid FROM garment2
WHERE garment2.garmentid = garment2order2.garmentid)
AND lounge2order2.lounge2orderid IN
(SELECT lounge2order2.lounge2orderid FROM lounge2order2
WHERE lounge2order2.lounge2orderid = orders2.lounge2orderid)
AND lounge2.loungeid IN
(SELECT lounge2.loungeid FROM lounge2
WHERE lounge2.loungeid = lounge2order2.loungeid)

First of all, try to avoid FROM orders2, branch2, garment2, garment2order2, lounge2, lounge2order2 it must be JOIN ... ON statement. That would help you to debug and us to understand what your logic and table relations are.
And to have any agregate functions like SUM or COUNT working you should set GROUP BY statement.
Since I have no idea what is your database structure like.
Here is my try:
SELECT
orders2.orderid,
orders2.orderdate,
COUNT(orders2.garment2orderid) AS 'no gar orders',
branch2.branchname,
SUM(garment2.hireprice) as 'total gar sold',
SUM(IF(orders2.lounge2orderid IS NULL,1,0)) as 'No of lounge sales',
SUM(lounge2.hirerate)
FROM orders2
LEFT JOIN branch2
ON branch2.branchid = orders2.branchid
LEFT JOIN garment2order2
ON garment2order2.garment2orderid = orders2.garment2orderid
LEFT JOIN garment2
ON garment2.garmentid = garment2order2.garmentid
LEFT JOIN lounge2order2
ON lounge2order2.lounge2orderid = orders2.lounge2orderid
LEFT JOIN lounge2
ON lounge2.loungeid = lounge2order2.loungeid)
WHERE orders2.branchid = 2
AND YEAR(orders2.orderdate)= 2011
GROUP BY orders2.orderid

Related

mysql: duplicate column name on join with subquery

I've searched a lot but I still don't get it.
Here's my sample code
SELECT sp.testno, sp.companyid, st.*
FROM sponsor AS sp
LEFT JOIN
(
SELECT a.sponsorempno, (CASE WHEN t.companyid IS NULL OR t.companyid = '' THEN'aa' ELSE t.companyid END) agncy, a.controlno, a.tnpl, t.*
FROM applicant AS a
LEFT JOIN
test AS t
ON a.controlno = t.controlno
) AS st
ON sp.testno = st.testno
I still returns an error:
#1060 - Duplicate column name 'controlno'
Can somebody tell me what's wrong with the code?
In the subselect of your join, you are selecting a.controlno and by t.* t.controlno.
You should provide an alias for one of the selected columns. In your case a.controlno. This is necessary, because the table aliases of the inner select are lost, when accessing it from the outer one.
The statement below should work, if there aren't any other duplicate column names in test and the set of used columns from applicant.
SELECT sp.testno, sp.companyid, st.*
FROM sponsor AS sp
LEFT JOIN
(
SELECT a.sponsorempno, (CASE WHENt.companyid IS NULL OR t.companyid = '' THEN'aa' ELSE t.companyid END) agncy, a.controlno as a_controlno, a.tnpl, t.*
FROM applicant AS a
LEFT JOIN
test AS t
ON a.controlno = t.controlno
) AS st
ON sp.testno = st.testno

MYSQL SELECT is slow when crossing multiple tables

I have a mysql query which is to return the only 1 record that need to cross multiple table. However, the mysql query is slow when executing.
Query:
SELECT *,
(SELECT TreeName FROM sys_tree WHERE TreeId = Mktg_Unit_Booking.ProjectLevelId) AS PhaseName,
(CASE WHEN ProductType = 'U' THEN (SELECT UnitNo FROM prop_unit pu WHERE pu.UnitId = mktg_unit_booking.UnitId)
ELSE (SELECT BayNo FROM prop_car_park pcp WHERE pcp.CarParkId = UnitId) END) AS UnitNo,
(SELECT CustomerName FROM mktg_customer mc WHERE mc.CustomerId = mktg_unit_booking.CustomerId) AS CustomerName
FROM Mktg_Unit_Booking
WHERE IsDeleted <> '1' AND IsApproved = '1'
AND UnitId = 1110 AND ProductType = 'U'
ORDER BY UnitNo
I have run EXPLAIN in the query and I got this:
Any other suggestion on how to improve the speed of the query?
Thank you!
you are doing the cross product, instead of that you should use join.
Don't use sub-queries in select statement instead use proper join on Mktg_Unit_Booking in after from statement.
you query should something look like :
select
sys_tree.TreeName AS PhaseName,
case
WHEN Mktg_Unit_Booking.ProductType = 'U' then prop_unit.UnitNo
else prop_car_park.BayNo
end as UnitNo,
mktg_customer.CustomerName AS CustomerName
FROM Mktg_Unit_Booking
left join sys_tree on sys_tree.TreeId = Mktg_Unit_Booking.ProjectLevelId
left join prop_unit on prop_unit.UnitId = Mktg_Unit_Booking.UnitId
left join prop_car_park on prop_car_park.CarParkId = Mktg_Unit_Booking.UnitId
left join mktg_customer on mktg_customer.CustomerId = Mktg_Unit_Booking.CustomerId
WHERE IsDeleted <> '1' AND IsApproved = '1'
AND UnitId = 1110 AND ProductType = 'U'
ORDER BY UnitNo;
I have assumed that each table consists of only 1 matching tuple. If there are more then your logic needs to be modified.

sql inner join query can use value of outer query?

The below runs fine :
select Runs.runId,Runs.prodId,fail,Owner,
(cast(counts.Count as decimal(4,2))) as PercentAnalysed,Language,Platform
from Runs AS Runs Inner Join Product AS Product On Runs.prodId=Product.prodId
left join (SELECT COUNT(*) AS 'Count', Results.runId
FROM Results inner join Runs on Results.runId=Runs.runId
WHERE Analysed = 'True'
GROUP BY Results.runId ) counts on counts.runId = Runs.runId
I want PercentAnalysed value in outer query to be as below :
= [counts.Count/failCount] if failCount !=0
or
=[0] if failCount=0
How do I do this ?
Any idea anyone ?
You need to use the CASE statement to get what you want.
SELECT
Runs.runId,
Runs.prodId,
fail,
Owner,
CAST(CASE WHEN failcount <> 0 THEN counts.Count/failcount
WHEN failcount = 0 OR counts.Count IS NULL THEN 0
ELSE counts.Count END AS Decimal(4,2)) PercentAnalysed,
Language,
Platform
FROM
.....

SOQL: Avoid count with NULL results return 0 (zero) instead

I have a problem, I have written a query and I need to return the count of opportunities in the given order: Name1, Name2, Name3, Name4. The problem is that if the count is NULL for example for Name2, then the query returns Name1_count, Name3_count, Name4_count.
I need to make sure that I always get the values in the right order and if the value is null i need to get back 0. But its not working :(
I tried:
Select Owner.Name
,IF(ISBLANK(count(id))
,0
,count(id))
from Opportunity
where CloseDate = Today
and Approved__c = true
and (Owner.Name = 'Name1'
or Owner.Name = 'Name2'
or Owner.Name = 'Name3'
or Owner.Name = 'Name4')
group by Owner.Name
Your query uses a table alias called owner which is not defined. Presumably, this is supposed to refer to Opportunity, although that is just a guess. Also, to get a 0 when you have a NULL, the typical function is coalesce(). And I replaced the complicated set of ors with in:
Select o.Name, coalesce(count(id), 0)
from Opportunity o
where CloseDate = Today and Approved__c = true and
o.Name in ('Name1', 'Name2', 'Name3', 'Name4')
group by o.Name ;
Finally, to get all four names in the output, you need to use left outer join:
Select names.Name, count(o.id) as cnt
from (select 'Name1' as name union all select 'Name2' union all
select 'Name3' union all select 'Name4'
) names left outer join
Opportunity o
on names.name = o.name
where CloseDate = Today and Approved__c = true
group by names.Name ;

SQL Query Help - Joining Multiple Columns Based On Condition [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
SQL query help - have two where conditons in join condition
I have the following tables with the columns as below. I have mentioned what I need from this. I already posted a link in here SQL query help - have two where conditons in join condition with what I have been trying but cannot get this through. Once again positing it plainly with what I need:
Book
BookId, BookName
Desk
DeskId, BookId ,DeskName
CounterParty
CPId, CpName
Trade
TradeId, Buyer, Seller
This is how the Buyer and Seller data would be :
Buyer Seller
B3232 B323
C32 B222
B323 C323
Based on the starting character B or C in these two columns, I need to join Book or CP table to check the ids.
I need **t.TradingDeskName, b.BookName, c.CpName, t.Buyer, t.Seller.**
Any help is very much appreciated.
Thanks,
mani
p.s : I am trying to get this done through SQL or Linq to Sql.
The recent query but have more to fix :
SELECT DISTINCT desk.Name as TradingDeskName, b.Name as Book, t.Seller, t.Buyer, c.PartyName, FROM TradingDesk AS desk
RIGHT JOIN Book as b
ON b.TradingDeskId = d.Id
RIGHT JOIN Trade as t
ON LEFT(t.Buyer, 1) = 'B' AND SUBSTRING(t.Buyer, 2, len(t.Buyer)) = b.Id
LEFT JOIN Book as b1
ON LEFT(t.Seller, 1) = 'B' AND SUBSTRING(t.Seller, 2, len(t.Seller)) = b1.Id
LEFT JOIN CounterParty as c
ON LEFT(t.Buyer, 1) = 'C' AND SUBSTRING(t.Buyer, 2, len(t.Buyer)) = c.PartyId
LEFT JOIN CounterParty as c1
ON LEFT(t.Seller, 1) = 'C' AND SUBSTRING(t.Seller, 2, len(t.Seller)) = c1.PartyId
As I mentioned I need :
Desk.Name - B.Name - T.Seller - T.Buyer- C.PartyName
The C.PartyName will have the value if T.Seller or T.Buyer value is starting with 'C' (from CounterParty Table) else will be null.
With the above query, I have null values coming in Desk.Name, B.Name and the logic of gettig C.PartyName is also not working.
There are a couple ways I could think of for achieving the desired results but because first things should come first, I'd suggest to modify the DB design if it is at all possible.
So, here are the 2 queries that I could work out:
Query 1
SELECT `t`.*,
(CASE
WHEN LEFT(`t`.`Buyer`, 1) = 'B' THEN
(SELECT `b`.`BookName`
FROM `Book` `b`
WHERE `b`.`BookId` = SUBSTRING(`t`.`Buyer`, 2))
ELSE (SELECT `c`.`CPName`
FROM `CounterParty` `c`
WHERE `c`.`CPId` = SUBSTRING(`t`.`Buyer`, 2))
END) AS `buyer_name`,
(CASE
WHEN LEFT(`t`.`Seller`, 1) = 'B' THEN
(SELECT `b`.`BookName`
FROM `Book` `b`
WHERE `b`.`BookId` = SUBSTRING(`t`.`Seller`, 2))
ELSE (SELECT `c`.`CPName`
FROM `CounterParty` `c`
WHERE `c`.`CPId` = SUBSTRING(`t`.`Seller`, 2))
END) AS `seller_name`
FROM `Trade` `t`
Query 2
SELECT *
FROM `Trade` `t`
LEFT JOIN `Book` `b` ON LEFT(`t`.`Buyer`, 1) = 'B' AND SUBSTRING(`t`.`Buyer`, 2) = `b`.`BookId`
LEFT JOIN `Book` `b1` ON LEFT(`t`.`Seller`, 1) = 'B' AND SUBSTRING(`t`.`Seller`, 2) = `b1`.`BookId`
LEFT JOIN `CounterParty` `c` ON LEFT(`t`.`Buyer`, 1) = 'C' AND SUBSTRING(`t`.`Buyer`, 2) = `c`.`CPId`
LEFT JOIN `CounterParty` `c1` ON LEFT(`t`.`Seller`, 1) = 'C' AND SUBSTRING(`t`.`Seller`, 2) = `c1`.`CPId`;
Both the above queries return same results but in different formats. Please try and see which one works best for you.
Also, it isn't very clear from your question where does the table Desk fit in and what relations does it hold with other tables. Please feel free to add respective columns you'll need from Desk.
Please note that the suggested queries are in MySQL. It is not very clear what system are you running - you've mentioned in your post that you are trying using SQL or Linq SQL and in the tags you've mentioned everything + MySQL.
You could do it something like this (untested):
select
t.Buyer,
t.Seller,
case when t.Buyer like 'B%' THEN (select BookName from Book where BookId = t.Buyer)
ELSE (select CpName from Counterparty where CPId = t.Buyer)
end BuyerName,
case when t.Buyer like 'B%' THEN (select DeskName from Desk where BookId = t.Buyer)
ELSE NULL
end BuyerDeskName,
case when t.Seller like 'B%' THEN (select BookName from Book where BookId = t.Seller)
ELSE (select CpName from Counterparty where CPId = t.Seller)
end SellerName,
case when t.Seller like 'B%' THEN (select DeskName from Desk where BookId = t.Seller)
ELSE NULL
end SellerDeskName,
from
Trade t
The problem you have is that, since the table you want to join to is data driven, you can't specify it in the FROM clause..