LEFT OUTER JOIN AND WHERE on joining table - mysql

To elaborate, I'm selecting fields from item and locations tables. Connection is location_id from items table and id field from locations table. After join I'm doing WHERE statement on city_text field from locations table.
Is this legal action since I'm doing WHERE on field from second table?
SELECT uc_items.* ,
uc_users_store.id AS store_id,
uc_users_store.store_name,
uc_users_store.address,
uc_users_store.work_hours,
uc_locations.city_text AS city,
uc_locations.zipcode_text AS zipcode,
uc_locations.state_text AS STATE,
uc_locations.country_text AS country
FROM uc_items
LEFT OUTER JOIN uc_users_store ON uc_items.store_id=uc_users_store.id
LEFT OUTER JOIN uc_locations ON uc_users_store.store_location_id=uc_locations.id
WHERE uc_locations.city_text LIKE "%'.$city.'%"
AND uc_items.iname LIKE "%'.$description.'%"
AND uc_items.expiration_stamp > '.time().'
ORDER BY uc_items.posting_stamp DESC,
uc_items.discount DESC

It's legal, but might lead to unexpected results if the tested value is NULL. However, you could catch these situations by including an IS NULL check.
For instance
WHERE (col = 'value' OR col IS NULL)

Completely legal. However it would be a lot more logical to use INNER JOIN instead of LEFT JOIN since your WHERE statement is concerning the table you are joining to. A pseudo example:
SELECT t1.something, t2.somethin FROM first_table t1 INNER JOIN second_table t2 ON t1.some_id = t2.some_id_from_t1 WHERE t2.some_column='something'

Related

Avoid Duplicate in Mysql Left Join Query

i have to take data from three tables like Userdetails,tasks,timedetails so i am getting data but it is duplicating based on the timedetails table. for example person id is - 1. it is presented two times in timedetails table then i'm getting duplicate rows.
my query is
SELECT GROUP_CONCAT(B.task_status) as task_status,
GROUP_CONCAT(B.task_type) as task_type,
GROUP_CONCAT(B.task_id) as task_id,
GROUP_CONCAT(B.task_name) as task_name,
A.us_id,
A.us_name,
C.out_time
FROM ts_userdetails A
LEFT JOIN
cms_task B
ON B.emp_id = A.us_id
LEFT JOIN
ts_timedetails C
ON C.user_id=A.us_id
WHERE C.entry_date='2017-05-09' AND
A.us_id!='1'
GROUP BY C.user_id
I am getting results like
I don't want duplicated things in displayed fields.
If I have 2 timedetails for one particular person id means 2 times duplication occurs. I just want one time.
use distinct keyword
SELECT GROUP_CONCAT(distinct B.task_status) as task_status,GROUP_CONCAT(distinct B.task_type) as task_type,GROUP_CONCAT(distinct B.task_id) as task_id,GROUP_CONCAT(distinct B.task_name) as task_name,A.us_id,A.us_name,C.out_time FROM ts_userdetails A LEFT JOIN cms_task B ON B.emp_id = A.us_id LEFT JOIN ts_timedetails C ON C.user_id=A.us_id WHERE C.entry_date='2017-05-09' AND A.us_id!='1' GROUP BY C.user_id

Left Join - Unknown Column?

Can you assist me with my query? I keep receiving an error that states "Error Code: 1054. Unknown column 'cdata.customerid' in 'on clause'"
If I want to attach the left join data where the customer id's match from customerdata table and order table, how can I achieve this? I must not understand at what point SQL allows data to become accessible by different parts of the query.
select
cdata.customerid,
cdata.affiliate,
cdata.firstname,
cdata.address1,
cdata.address2,
cdata.city,
cdata.state,
cdata.postalcode,
cdata.emailaddress,
cdata.active
from customerdata cdata, order a
left join
(select
a.transactiondate,
sum(a.TransactionAmount),
a.id
from order a
group by a.id)
txns on a.id = cdata.customerid
where cdata.active = "A";
In on clause you have to specify fields that belong to the tables which are taking part in join clause. So, if you are joining cdata with the txns subquery, you have to probably join on txns.id and cdata.customerid. You probably also wanted to get your sum out of your subquery, so you have to include this field in your main SELECT clause. And you probably have to specify transactiondate field in your group by clause, at least this is necessary for ORACLE DB, I am not sure if this is the case for MySQL:
select
cdata.customerid,
cdata.affiliate,
cdata.firstname,
cdata.address1,
cdata.address2,
cdata.city,
cdata.state,
cdata.postalcode,
cdata.emailaddress,
cdata.active,
txns.tsum,
txns.transactiondate
from customerdata cdata
left join
(select
a.transactiondate,
sum(a.TransactionAmount) tsum,
a.id
from order a
group by a.id, a.transactiondate) txns
on txns.id = cdata.customerid
where cdata.active = "A";
The JOIN references the table 'order' and the table 'txns', 'cdata' is not involved here, so within the context of the join cdata.customerid does not exist.

Creating a subquery in Access

I am attempting to create a subquery in Access but I am receiving an error stating that one record can be returned by this subquery. I am wanting to find the top 10 companies that have the most pets then I want to know the name of those pets. I have never created a subquery before so I am not sure where I am going wrong. Here is what I have:
SELECT TOP 10 dbo_tGovenrnmentRegulatoryAgency.GovernmentRegulatoryAgency
(SELECT dbo_tPet.Pet
FROM dbo_tPet)
FROM dbo_tPet INNER JOIN dbo_tGovenrnmentRegulatoryAgency ON
dbo_tPet.GovernmentRegulatoryAgencyID =
dbo_tGovenrnmentRegulatoryAgency.GovernmentRegulatoryAgencyID
GROUP BY dbo_tGovenrnmentRegulatoryAgency.GovernmentRegulatoryAgency
ORDER BY Count(dbo_tPet.PetID) DESC;
Consider this solution, requiring a subquery in the WHERE IN () clause:
SELECT t1.GovernmentRegulatoryAgency, dbo_tPet.Pet,
FROM dbo_tPet
INNER JOIN dbo_tGovenrnmentRegulatoryAgency t1 ON
dbo_tPet.GovernmentRegulatoryAgencyID = t1.GovernmentRegulatoryAgencyID
WHERE t1.GovernmentRegulatoryAgency IN
(SELECT TOP 10 t2.GovernmentRegulatoryAgency
FROM dbo_tPet
INNER JOIN dbo_tGovenrnmentRegulatoryAgency t2 ON
dbo_tPet.GovernmentRegulatoryAgencyID = t2.GovernmentRegulatoryAgencyID
GROUP BY t2.GovernmentRegulatoryAgency
ORDER BY Count(dbo_tPet.Pet) DESC);
Table aliases are not needed but I include them for demonstration.
This should hopefully do it:
SELECT a.GovernmentRegulatoryAgency, t.NumOfPets
FROM dbo_tGovenrnmentRegulatoryAgency a
INNER JOIN (
SELECT TOP 10 p.GovernmentRegulatoryAgencyID, COUNT(p.PetID) AS NumOfPets
FROM dbo_tPet p
GROUP BY p.GovernmentRegulatoryAgencyID
ORDER BY COUNT(p.PetID) DESC
) t
ON a.GovernmentRegulatoryAgencyID = t.GovernmentRegulatoryAgencyID
In a nutshell, first get the nested query sorted, identifying what the relevant agencies are, then inner join back to the agency table to get the detail of the agencies so picked.

How do I create a 3-way LEFT JOIN with MYSQL?

I'm attempting to create a 3-way LEFT JOIN using MYSQL and I'm having difficulty accomplishing it so I figured this would be the place to figure it out.
I have a three tables as I'll display below. The first contains a list of items that a user has added to their queue to be processed by the game. The other two contain details about each of the items such as their strengths, points to completion, etc. In the queued table, I have two types of items, units and research. The unit details are found in table 2 and the research details are found in table 3.
Table 1: The first table (core_queued_units) contains the following fields: id, unit_id, name, location, class(unit or research),sort.
Table 2: The second table (core_available_units) contains the following fields: id, name, description, etc.
Table 3: The third table (core_available_tech) contains the following fields: id, name, description, etc.
FROM core_queued_units
LEFT JOIN core_available_units
ON core_queued_units.unit_id = core_available_units.id
AND core_queued_units.class='Unit'
LEFT JOIN core_available_tech
ON core_queued_units.unit_id = core_available_tech.id
AND core_queued_units.class='Research'
WHERE core_queued_units.location = '1'
AND core_queued_units.user_id ='".$GLOBALS['self']['usrID']."'
ORDER BY core_queued_units.sort ASC
If fields in core_available_units and core_available_tech are equal, you can try this:
SELECT *
FROM core_queued_units cq
LEFT JOIN (
select cau.*, 'Unit' class from core_available_units cau
union all
select cat.*, 'Research' class from core_available_tech cat) c
ON cq.unit_id = c.unit_id and c.class = cq.class
WHERE cq.location = '1'
AND cq.user_id ='".$GLOBALS['self']['usrID']."'
ORDER BY cq.sort ASC
If you are trying to join multiple tables, you can do as follows. I am taking Table1 as base table.
SELECT columnname1, columnname2......
FROM Table1
LEFT OUTER JOIN Table2 ON Table1.PK = Table2.FK (here Table2.FK is the Primary key of Table1 which is used as Foreign key in Table2)
LEFT OUTER JOIN Table3 ON Table1.PK = Table3.FK (same condition as above)
WHERE insert your conditions here
using this sample, columns from Table2 & Table3 will added at the right most side of Table1.
Please inform if this helps.
Can you try to swap the arguments in the On-clause
core_queued_units.unit_id = core_available_tech.id?

Left Join not returning all rows

I have this query in MySQL:
SELECT pr.*, pr7.value AS `room_price_high`
FROM `jos_hp_properties` pr
LEFT OUTER JOIN `jos_hp_properties2` pr7 ON pr7.property=pr.id
WHERE pr7.field=23
The jos_hp_properties table has 27 rows but the query only returns one. Based on this question I think it may be because of the WHERE clause. The jos_hp_properties2 table has fields id, property, field, value, where field is a foreign key to a third table (which I don't need to get data from).
Is there a way to select all the rows from the first table, including the value from table #2 where the field is 23 (or NULL if there is no field 23)?
Sure. Move the WHERE condition to the JOIN:
SELECT pr.*, pr7.value AS `room_price_high`
FROM `jos_hp_properties` pr
LEFT JOIN `jos_hp_properties2` pr7
ON pr7.property=pr.id
AND
pr7.field=23
You must place the pr7 criteria in the join, not in the where clause. The where clause works on the entire result set AFTER the join has been performed.
SELECT pr.*, pr7.value AS `room_price_high`
FROM `jos_hp_properties` pr
LEFT OUTER JOIN `jos_hp_properties2` pr7 ON pr7.property=pr.id and pr7.field=23
Try this:
SELECT pr.*, pr7.value AS `room_price_high`
FROM `jos_hp_properties` pr
LEFT OUTER JOIN `jos_hp_properties2` pr7 ON pr7.property=pr.id
WHERE (pr7.field=23 OR pr7.field is null)
You can also use a CTE (Common Table Expression) to do the select, then use the CTE to do the left join..
wrc (parentid, childid) as (
select parentid, childid
from placechild
where relationshipid in (select id from placerelationship where relationship = 'Winter Region Capital')
),
stw (cnid, coid, capid, st_or_te, sid, scid,wcid) as (
select s.cnid, s.coid, s.capid, s.st_or_te, s.sid, s.scid, w.childid
from stcap s
left join wrc w
on s.sid = w.parentid
)
select * from stw