Outer Join with Multiple Inner Join In a Single Query - sql-server-2008

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.

Related

SQL - return rows that do not have a certain value

looking for a bit of help here if possible?
I have the following query:-
On or database we have a table called Linkfile, in this table are "Types" all beginning with "YG". I need to return those rows that do not have the type of "YG8" but just cannot seem to do it. I know ill need to use a sub query but am stuck!
This is my code and the fields I need to return. I just need to only show those that do not have the lk.type of "YG8"
select distinct l.description, p.displayname AS Temp, p.compliance_status As 'Compliant', lk.displayname, lk.type
from event e
inner join organisation o on e.organisation_ref = o.organisation_ref
inner join opportunity opp on e.opportunity_ref = opp.opportunity_ref
inner join event_role ev on ev.event_ref = e.event_ref
inner join address a on a.address_ref = opp.address_ref
inner join person p on ev.person_ref = p.person_ref
inner join lookup l on p.responsible_team = l.code
inner join person_type pt on p.person_ref = pt.person_ref
inner join linkfile lk on lk.parent_object_ref = pt.person_ref
where o.displayname LIKE '%G4S%' and p.compliance_category = '$016'
and lk.type like 'YG%' and l.code_type = '2'
and a.displayname LIKE '%MOJ%'
and pt.status = 'A'
order by l.description, p.displayname, lk.type
Use below query :
select distinct l.description, p.displayname AS Temp, p.compliance_status As 'Compliant', lk.displayname, lk.type,lk.parent_object_ref
from event e
inner join organisation o on e.organisation_ref = o.organisation_ref
inner join opportunity opp on e.opportunity_ref = opp.opportunity_ref
inner join event_role ev on ev.event_ref = e.event_ref
inner join address a on a.address_ref = opp.address_ref
inner join person p on ev.person_ref = p.person_ref
inner join lookup l on p.responsible_team = l.code
inner join person_type pt on p.person_ref = pt.person_ref
left join (select displayname, type,parent_object_ref from linkfile where lk.type like 'YG8%' )lk on lk.parent_object_ref = pt.person_ref
where o.displayname LIKE '%G4S%' and p.compliance_category = '$016' and lk.parent_object_ref is null
and l.code_type = '2'
and a.displayname LIKE '%MOJ%'
and pt.status = 'A'
order by l.description, p.displayname, lk.type;
I've used left join on linkfile with type like 'YG8%' and fetching the only records which are not matched
I think you can just replace the
lk.type like 'YG%'
with the following:
(lk.type >= 'YG' and lk.type <'YG8') or (lk.type > 'YG8' and lk.type <='YGZ')
this should accomplish what you are trying to do and also avoid using "like" which is less efficient (assuming you have an index on lk.type, at least).
You may refine this a bit by knowing which are the possible values of lk.type of course. I.e. what are the extremes for the YG "subtype"? YG00-YG99? YG-YGZ?
(Be especially careful if you may have YG81 or YG87 for example, because then my clause will not work properly... on the other hand if your YG subtype can have values like YG34 it would have been better to use YG08 instead of YG8)

copy a value from mysql query if one is empty

I am having a problem with a query that sometimes, will have an empty field returned. I have tried to use CASE and COALESCE but I am likely constructing the query incorrectly.
What I need to do in the results is, if b.user_id returns empty, to copy the value from a.useracctid into b.user_id. I hope that makes sense???
Here is my query, no matter what I have tried it errors for me.
Thank you for any idea or hints you can provide
SELECT b.user_id,a.responsetime,a.latitude,a.longitude,
a.status,a.updatetime,c.address
FROM callouts_response a
LEFT JOIN ldap_user_accounts b on a.useracctid = b.id
LEFT JOIN callouts c on a.calloutid = c.id
WHERE calloutid = :cid
Not sure how you have used COALESCE() but you can do like
SELECT COALESCE(b.user_id,a.useracctid) as somecol,
a.responsetime,
a.latitude,
a.longitude,
a.status,
a.updatetime,
c.address
FROM callouts_response a
LEFT JOIN ldap_user_accounts b on a.useracctid = b.id
LEFT JOIN callouts c on a.calloutid = c.id
WHERE a.calloutid = :cid
Try this:
SELECT IF(b.user_id IS NULL, a.useracctid, b.user_id), a.responsetime,a.latitude,a.longitude,
a.status,a.updatetime,c.address
FROM callouts_response a
LEFT JOIN ldap_user_accounts b on a.useracctid = b.id
LEFT JOIN callouts c on a.calloutid = c.id
WHERE calloutid = :cid

MySQL Inner Join not returning correct value

I have a question in my query. why I can't filter using a.train_num?. The result is always 0. But when I filter using c.stridnumber then I am getting result.
please check my below query.
SELECT a.*,b.*,c.*
FROM pos_train_db a
INNER JOIN emp_db b
ON a.pos_name = b.emp_position
INNER JOIN tms_ml c
ON b.ID = c.stridnumber
WHERE a.train_num=10
Try this:
$this->sql =
"SELECT a.*,b.*,c.* FROM pos_train_db a
LEFT JOIN emp_db b ON a.pos_name = b.emp_position
LEFT JOIN tms_ml c ON b.ID = c.stridnumber
WHERE a.train_num=10 ";

MySQL / PHP - 2 different arguments for 1 table

I have the following SQL:
$queryString = "
SELECT
iR.lastModified,
d.*,
c2.title as stakeholderTitle,
u.username as authorUsername,
c.title as authorContactName,
GROUP_CONCAT(iR.stakeholderRef) AS participants
FROM
informationRelationships iR,
contacts c2
INNER JOIN
debriefs d ON
d.id = iR.linkId
LEFT JOIN
users u ON
u.id = iR.author
LEFT JOIN
contacts c ON
c.ref = u.contactId
LEFT JOIN
debriefs d2 ON
d2.stakeholder = c2.ref
WHERE
(
iR.clientRef = '$clientRef' OR
iR.contactRef = '$contactRef'
)
AND
iR.projectRef = '$projectRef' AND
iR.type = 'Debrief'
GROUP BY
iR.linkId
ORDER BY
d.dateOfEngagement
";
notice how I require 2 different bits of data for the the contacts table.
So at one point, I need to match
c.ref = u.contactId
This will return one bit of information
but I also need a completely different grouping:
d2.stakeholder = c2.ref
Problem is that the title is the column i'm interested in for both:
c2.title as stakeholderTitle,
...
c.title as authorContactName
How do I go about doing this?
My current try is returning:
Error: Unknown column 'iR.linkId' in 'on clause'
I'm not sure I really understand what is happening here:
how to join two tables on common attributes in mysql and php?
EDIT::::---ANSWERED--zerkms
$queryString = "
SELECT
iR.lastModified,
d.*,
c2.title as stakeholderTitle,
u.username as authorUsername,
c.title as authorContactName,
GROUP_CONCAT(iR.stakeholderRef) AS participants
FROM
informationRelationships iR
INNER JOIN
debriefs d ON
d.id = iR.linkId
INNER JOIN
contacts c2 ON
d.stakeholder = c2.ref
LEFT JOIN
users u ON
u.id = iR.author
LEFT JOIN
contacts c ON
c.ref = u.contactId
WHERE
(
iR.clientRef = '$clientRef' OR
iR.contactRef = '$contactRef'
)
AND
iR.projectRef = '$projectRef' AND
iR.type = 'Debrief'
GROUP BY
iR.linkId
ORDER BY
d.dateOfEngagement
";
By re-ordering my query I have managed to get both columns in... Thanks zerkms!
You cannot mix implicit joins and explicit joins in a single query in mysql.
So
FROM informationRelationships iR,
contacts c2
should be rewritten to
FROM informationRelationships iR
INNER JOIN contacts c2 ON ...
Do not use cartesian product and joins in the same query (not subquery), here, use only joins (CROSS JOIN is the same as cartesian product).

SQL returns incorrect data using 2 left joins

I have written a MYSQL script, that returns incorrect data. I am quite fluent in SQL, but this query is not returning correct results. Can someone have a look and see whats going on. The problem is the noOfBids, and noOfRatedTimes. The values are the same for both columns and are large values too.
select
a.user_name as userName,
coalesce(count(b.sp_user_name),0) as noOfBids,
coalesce(ROUND(AVG(b.a_amount),2),0) as avgAmount,
coalesce(count(d.sp_user_name),0) as noOfRatedTimes,
coalesce(ROUND(AVG(d.user_rate),2),0)
from users a
left join project_imds b
on b.sp_user_name = a.user_name
left join projects c
on b.project_code = c.project_code
left join sp_user_rating d
on d.sp_user_name = b.sp_user_name
where a.user_type = 'SP'
and a.active = 'Y'
group by a.user_name
order by coalesce(ROUND(AVG(d.user_rate),2),0) desc;
I have created a workaround on this, by creating a temp table to get the avg values and joining this to the main query.
Since I don't know the specifics of the data behind your query, this is only a guess. But perhaps you'd rather join "sp_user_rating" directly to "users", changing
left join sp_user_rating d
on d.sp_user_name = b.sp_user_name
to
left join sp_user_rating d
on d.sp_user_name = a.user_name
select
a.user_name as userName,
coalesce(count(b.sp_user_name),0) as noOfBids,
coalesce(ROUND(AVG(b.a_amount),2),0) as avgAmount,
coalesce(count(d.sp_user_name),0) as noOfRatedTimes,
coalesce(ROUND(AVG(d.user_rate),2),0)
from users as a
left join project_imds as b
on b.sp_user_name = a.user_name
left join projects as c
on b.project_code = c.project_code
left join sp_user_rating as d
on d.sp_user_name = b.sp_user_name
where a.user_type = 'SP'
and a.active = 'Y'
group by a.user_name
order by coalesce(ROUND(AVG(d.user_rate),2),0) desc;