MySQL CASE LEFT JOINS returning NULL - mysql

I have a query with a CASE statement that determines the variable object_name this variable is derived from either the x_ambitions table or the x_trybes table. The queries below were combined so that I could keep it simple by just executing one SQL query.
I've split the SELECT statement into two so that you have a better understanding. The two queries below. Work and pull the correct object_name from the database.
The problem I'm having when I combine the two queries is that the cases 'new_join_ambition','new_created_ambition','new_liked_ambition' object_name returns NULL in the LEFT JOIN.
In the combined query, If I bring the cases: 'new_join_ambition','new_created_ambition','new_liked_ambition' above the 'new_join_trybe','new_created_trybe','new_liked_trybe' cases. The opposite happens. The trybe rows return NULL.
The two SQL queries:
A: (Retrieve Object A)
SELECT
s.id,
s.object_id,
s.type,
s.postee_id,
s.user_id,
s.text,
s.registered,
CONCAT(u.x_first_name,' ',u.x_last_name) AS postee_name,
ui.image_id AS postee_image_id,
CASE s.type
WHEN 'new_join_ambition'
OR 'new_created_ambition'
OR 'new_liked_ambition'
THEN a.name
ELSE 'a'
END AS object_name
FROM
x_share s
LEFT JOIN
x_user u ON u.id = s.postee_id
LEFT JOIN
x_user_images ui ON ui.user_id = s.postee_id
LEFT JOIN
x_ambitions a ON s.type IN ('new_join_ambition', 'new_created_ambition', 'new_liked_ambition') AND s.object_id = a.id
LEFT JOIN
x_ambition_invites ai ON s.type IN ('new_join_ambition') AND s.object_id = ai.ambition_id AND s.postee_id = ai.to
LEFT JOIN
x_ambition_likes al ON s.type IN ('new_liked_ambition') AND s.object_id = al.ambition_id AND s.postee_id = al.profile_id
LEFT JOIN
x_ambition_owner aoo ON s.type IN ('new_created_ambition') AND s.object_id = aoo.ambition_id
WHERE
s.user_id = '%s'
ORDER BY
s.registered DESC
B: (Retrieve Object B)
SELECT
s.id,
s.object_id,
s.type,
s.postee_id,
s.user_id,
s.text,
s.registered,
CONCAT(u.x_first_name,' ',u.x_last_name) AS postee_name,
ui.image_id AS postee_image_id,
CASE s.type
WHEN 'new_join_trybe'
OR 'new_created_trybe'
OR 'new_liked_trybe'
THEN t.name
ELSE 'a'
END AS object_name
FROM
x_share s
LEFT JOIN
x_user u ON u.id = s.postee_id
LEFT JOIN
x_user_images ui ON ui.user_id = s.postee_id
LEFT JOIN
x_trybes t ON s.type IN ('new_join_trybe', 'new_created_trybe', 'new_liked_trybe') AND s.object_id = t.id
LEFT JOIN
x_trybe_invites ti ON s.type IN ('new_join_trybe') AND s.object_id = ti.trybe_id AND s.postee_id = ti.to
LEFT JOIN
x_trybes_likes tl ON s.type IN ('new_liked_trybe') AND s.object_id = tl.trybe_id AND s.postee_id = tl.profile_id
LEFT JOIN
x_trybe_owner too ON s.type IN ('new_created_trybe') AND s.object_id = too.trybe_id
WHERE
s.user_id = '%s'
ORDER BY
s.registered DESC
I've ran both the queries and have captured images of the results of both queries.
Set A:
Set B:
How can I combine the two without the object_name returning NULL? If you have any questions please use the comments and I'll reply without hesitation.
Thanks in advance

I don't know about the rest of your query, but your case statement is incorrect. You have:
(CASE s.type
WHEN 'new_join_ambition' OR 'new_created_ambition' OR 'new_liked_ambition'
THEN a.name
ELSE 'a'
END) AS object_name
The ORs end up treating the values as numbers, so this is equivalent to WHEN 0 THEN . . ..
What you want is this form of the case:
(CASE WHEN s.type IN ('new_join_ambition', 'new_created_ambition', 'new_liked_ambition')
THEN a.name
ELSE 'a'
END) AS object_name

Related

MySQL - I want my table JOIN to return a single row based on a condition

in the below code there are multiple entries in 'leads' table with the same 'account_id'. I want it to return a single row - the one with the minimal value of another field 'date_entered'. I cannot use 'group by' on account_id as I intend to use 'group by' on BU and get summation accordingly. Please help.
select uc.business_unit_dp_c,
FORMAT(SUM(CASE
WHEN lc.source_leads_c not in ('Discovery','Discovery SuperEmail','Self Generated','Partner','Channel_Partner') and k.id<>'' THEN k.order_value
WHEN lc.source_leads_c not in ('Discovery','Discovery SuperEmail','Self Generated','Partner','Channel_Partner') and s.id<>'' THEN s.sivr_aiv_inr
ELSE 0
END),0)
as Online,
FORMAT(SUM(CASE
WHEN lc.source_leads_c in ('Discovery', 'Discovery SuperEmail') and k.id<>'' THEN k.order_value
WHEN lc.source_leads_c in ('Discovery', 'Discovery SuperEmail') and s.id<>'' THEN s.sivr_aiv_inr
ELSE 0
END),0)
as Discovery,
FORMAT(SUM(CASE
WHEN lc.source_leads_c in ('Partner','Channel_Partner') and k.id<>'' THEN k.order_value
WHEN lc.source_leads_c in ('Partner','Channel_Partner') and s.id<>'' THEN s.sivr_aiv_inr
ELSE 0
END),0)
as Self_Generated_CP
from opportunities as o
left join opportunities_cstm as oc on o.id=oc.id_c
left join opportunities_knw_caf_1_c as ok on o.id=ok.opportunities_knw_caf_1opportunities_ida
left join knw_caf as k on ok.opportunities_knw_caf_1knw_caf_idb=k.id
left join opportunities_knw_sivr_caf_1_c as os on os.opportunities_knw_sivr_caf_1opportunities_ida=o.id
left join knw_sivr_caf as s on s.id=os.opportunities_knw_sivr_caf_1knw_sivr_caf_idb
left join accounts_opportunities as ao on ao.opportunity_id=o.id
left join leads as l on l.account_id=ao.account_id and l.account_id <> ''
left join leads_cstm as lc on lc.id_c=l.id
left join users_cstm as uc on uc.id_c=o.assigned_user_id
where o.sales_stage='clw' and
(k.id<>'' or s.id<>'') and o.jira_raise_date <> '' and
(o.tranjection_type in ('Fresh Plan / New Customer','Number Activation','Revival','Balance Amount') or o.transaction_sivr in ('Paid Project','Number Allocation','New Feature')) and
o.jira_raise_date between '2016-06-01' and curdate()
group by uc.business_unit_dp_c
Write SQL just as you described
Select *
from from opportunities o
left join opportunities_cstm oc
on o.id = oc.id_c
left join opportunities_knw_caf_1_c ok
on o.id = ok.opportunities_knw_caf_1opportunities_ida
left join knw_caf k
on ok.opportunities_knw_caf_1knw_caf_idb = k.id
left join opportunities_knw_sivr_caf_1_c os
on os.opportunities_knw_sivr_caf_1opportunities_ida=o.id
left join knw_sivr_caf s
on s.id = os.opportunities_knw_sivr_caf_1knw_sivr_caf_idb
left join accounts_opportunities ao
on ao.opportunity_id=o.id
left join leads l
on l.account_id=ao.account_id
and l.account_id <> ''
left join leads_cstm lc
on lc.id_c = l.id
left join users_cstm uc
on uc.id_c = o.assigned_user_id
where o.sales_stage = 'clw' and
and (k.id <> '' or s.id <> '')
and o.jira_raise_date <> ''
and (o.tranjection_type in
('Fresh Plan / New Customer',
'Number Activation','Revival','Balance Amount') or
o.transaction_sivr in
('Paid Project','Number Allocation','New Feature'))
and o.jira_raise_date between '2016-06-01' and curdate()
-- next, add this additional predicate to Where clause...
use table w/DateEntered column
and date_entered =
(Select Min(date_entered)
From accounts_opportunities os
join tableWithDateEntered dr -- Table w/DateEntered
on ????? -- proper join criteria here
Where os.account_id = l.account_id)
--- or as constructed by op ( and simplified by me, since both account_id and date_entered are in table leads, that's the only table that needs to be referenced in the subquery).....
and l.date_entered =
(select min(date_entered)
from leads
where account_id = l.account_id)
select min(C.date),C.Customer_Code from (
select InvoiceNo,month(InvoiceDate) as date,Customer_Code,Createddate from tbl_Invoices A Inner Join tbl_customer B on A.customer_Code=B.CustomerCode
where YEAR(InvoiceDate)='2017'
and CustomerCode not in (select CustomerCode from tbl_customer where year(createddate) in (year(getdate())))
and CustomerCode not in (select customer_Code from tbl_Invoices where year(InvoiceDate) in (year(getdate())-1))
and CustomerCode in (select customer_Code from tbl_Invoices where year(InvoiceDate) not in (year(getdate())))
--group by Customer_Code,Createddate,InvoiceNo
)C group by C.Customer_Code

Outer Join with Multiple Inner Join In a Single Query

I want to use Outer Join with inner Join in a single query
Query:
select d.unit_name, a.tour_code, a.hub_code, b.name, c.pp_no, c.dte_of_expiry
from bkng_mst a , bkng_pax b, bkng_cust c, unit_mst d
where a.bkng_id = b.bkng_id
and b.unit_cde = d.unit_cde
and a.unit_cde = d.unit_cde
and b.cust_id = c.cust_id
and a.bkng_stat = 'CNF'
and b.bkng_pax_cancel_flg = 'N'
and a.bkng_id = 'XXXX'
Use Outer Join from Table pax_dtl pd on a.bkng_id=pd.bkng_id along with above query
UPDATED :
I think that, taking into account the information provided in your comments, the following query should be helpful:
SELECT DISTINCT
d.unit_name, a.tour_code, a.hub_code, b.name, c.pp_no, c.dte_of_expiry,
pd.bkng_id, pd.unit_name, pd.tour_code, pd.pax_name, pd.pnr_no, pd.fare_base, pd.is_block, pd.is_system
FROM
bkng_mst a
INNER JOIN bkng_pax b
ON a.bkng_id = b.bkng_id
INNER JOIN bkng_cust c
ON b.cust_id = c.cust_id
INNER JOIN unit_mst d
ON b.unit_cde = d.unit_cde
AND a.unit_cde = d.unit_cde
LEFT OUTER JOIN pax_dtl pd
ON a.bkng_id=pd.bkng_id
WHERE
a.bkng_stat = 'CNF'
AND b.bkng_pax_cancel_flg = 'N'
AND a.bkng_id = 'XXXX'
Because of 1 to many relation between bkng_mst and pax_dtl tables, the columns d.unit_name, a.tour_code, a.hub_code, b.name, c.pp_no, c.dte_of_expiry from above query will repeat only if for 1 particular bkng_id value there will be at least one different value among the columns pd.bkng_id, pd.unit_name, pd.tour_code, pd.pax_name, pd.pnr_no, pd.fare_base, pd.is_block.
I hope it might help you, but in case of any doubts please write.

Mysql multiple tables left join last table

I have checked several threads on here and cannot find the answer to my question....
I am trying to do a mysql query with multiple tables and left join the last table. It does not like the left join and gives me no results when I include it. Any help is greatly appreciated :)
(I am using Joomla)
query = "SELECT DISTINCT u.id as uid, CONCAT(u.first_name,' ',u.last_name) as name1,
u.grad as grad, u.opt_out as opt_out
FROM #__bl_teams as t, #__bl_regions as r, #__users as u
LEFT JOIN #__bl_paid as pd ON pd.u_id = u.id
WHERE u.team_id = t.id AND u.team_id != '' AND u.s_id = $sid
AND ((t.id = $tid)OR($tid=0)) AND (t.id IN ($teamsfull))
AND ( (t.id IN(".$tc_teams."))OR(".$tc_id." = 0))
AND ((r.id = ".$mid.")OR(".$mid." = 0))
AND ((r.s_id = ".$sid.")OR(".$mid." = 0))
AND ( (FIND_IN_SET(t.id,r.teams) )OR(".$mid." = 0) )
AND u.id NOT IN($paidrows) AND u.id NOT IN ($rsrows) GROUP BY u.id";
$db->setQuery($query, $pageNav->limitstart, $pageNav->limit);
$rows50 = $db->loadObjectList();
You are mixing old-style joins and new style joins. That is your problem. The table aliases aren't recognized throughout the from statement, the way you expect them to be. Buried in the documentation is this warning:
However, the precedence of the comma operator is less than of INNER
JOIN, CROSS JOIN, LEFT JOIN, and so on. If you mix comma joins with
the other join types when there is a join condition, an error of the
form Unknown column 'col_name' in 'on clause' may occur. Information
about dealing with this problem is given later in this section.
Simple rule: Never use commas in the from clause.
So, rewrite your query using explicit joins and that will fix the problem.
I don't know the ctual tables, but this query is too long and will have unexpected results results. Anyways, Left join the other tables too.
query = "SELECT DISTINCT u.id as uid, CONCAT(u.first_name,' ',u.last_name) as name1,
u.grad as grad, u.opt_out as opt_out
FROM #__users as u
LEFT JOIN #__bl_paid as pd ON pd.u_id = u.id
LEFT JOIN #__bl_teams as t ON t.u_id = u.id
LEFT JOIN #__bl_regions as r ON r.u_id = u.id
WHERE u.team_id != ''
AND u.s_id = $sid
AND ((t.id = $tid)
OR($tid=0))
AND (t.id IN ($teamsfull))
AND ( (t.id IN(".$tc_teams."))
OR(".$tc_id." = 0))
AND ((r.id = ".$mid.")
OR(".$mid." = 0))
AND ((r.s_id = ".$sid.")
OR(".$mid." = 0))
AND ( (FIND_IN_SET(t.id,r.teams) )
OR(".$mid." = 0) )
AND u.id NOT IN($paidrows)
AND u.id NOT IN ($rsrows)
GROUP BY u.id";

i need to do an sql with if then else to join tables if the field is not null?

i need an sql stament that will give me something like this where if a field is null it doesn't do the join
SELECT AdminID,tblapartments.NameNo, tblgarages.GarageID, tblclients.Name FROM tbladmin,tblclients,tblgarages,tblapartments WHERE tblclients.ClientID =tbladmin.ClientID AND
IF (tbladmin.ApartmentID != null)
{
tblapartments.ApartmentID = tbladmin.ApartmentID
}
AND If(tbladmin.GarageID != Null)
{
tblgarges.GarageID = tbladmin.GarageID
}
Unless I'm missing something, this should just be an outer join.
SELECT
AdminID,
tblapartments.NameNo,
tblgarages.GarageID,
tblclients.Name
FROM
tbladmin INNER JOIN tblclients ON tbladmin.ClientID = tblclients.ClientID
LEFT OUTER JOIN tblgarages ON tbladmin.GarageID = tblgarages.GarageID
LEFT OUTER JOIN tblapartments ON tbladmin.ApartmentId = tblapartments.ApartmentID
You can use LEFT JOINs, when the joined column does not exist in the other table the result is a lot of NULL fields:
SELECT AdminID,tblapartments.NameNo, tblgarages.GarageID, tblclients.Name
FROM tbladmin
INNER JOIN tblclients
ON tbladmin.ClientID = tblclients.CliendID
LEFT JOIN tblgarages
ON tbladmin.GarageID = tblgarages.GarageID
LEFT JOIN tblapartments
ON tbladmin.ApartmentID = tblapartments.ApartmentID
I do not believe that this type of if logic is SQL standard. You could possibly implement it in a procedural SQL langauge like PL/SQL, plpgsql ... however to accomplish what you after i think a left join what you should look at.
SELECT AdminID,tblapartments.NameNo, tblgarages.GarageID, tblclients.Name
FROM tbladmin a
join tblclients b on b.ClientID = a.ClientID
left join tblapartments c on c.ApartmentID = a.ApartmentID
left join tblgarges d on d.GarageID = a.GarageID

SQL calculating time between assignments

I have to write an SQL statement which contain a field that contain two different values consecutively but in the way I have wrote it, it return always null because it is interpreted as having the two value in the same time!
My conditions should be : (ci.field = 'Group' and ci.oldString = 'Triage' ) and (ci.field='assignee' and ci.newString is not NULL)
That means calculate time between: when the issue is assigned to group named Triage and when the issue is assigned to a person.
How can I fix it?
My SQL statement:
select TIMEDIFF(a.created,b.created)
from
(select g.created, g.issueid as groupid1
from changegroup g
join changeitem ci on (ci.groupid = g.id)
join jiraissue ji on (ji.id = g.issueid)
join project p on (p.id = ji.project)
join priority pr on (pr.id = ji.priority)
where ci.field = 'Group'
and ci.oldString = 'Triage'
and ci.field='assignee'
and ci.newString is not NULL
and p.pname = 'Test'
and pr.pname='P1'
and ji.created between '2011-08-11 14:01:00' and '2011-08-12 14:11:00'
) a
left join (
select ji.created, ji.id as groupid2
from jiraissue ji
join changegroup g on (g.issueid = ji.id)
join project p on (p.id = ji.project)
where p.pname = 'Test'
and ji.created between '2011-08-11 14:01:00' and '2011-08-12 14:11:00'
) b ON (a.groupid1 = b.groupid2);
This is the table from which I should retrieve data
See my comment about the quality of your question but a hint at how to solve this goes like (assuming you can make sure this doesn't create 1-n joins)
select groupid_orsomething_else, TIMEDIFF(a.created, b.created)
from yourtable
left join
(select groupid_orsomething_else, created
from yourtable
where field = 'Group' and oldstring is 'Triage'
) a
on a.groupid_orsomething_else = yourtable.groupid_orsomething_else
left join
(select groupid_orsomething_else, created
from yourtable
where field = 'assignee' and oldstring is null) b
on b.groupid_orsomething_else = yourtable.groupid_orsomething_else