SELECT
fromData.name as fromname, toData.name as toName, prodData.prodname,
t1.`from_id`, t1.`to_id` , t1.`product_id` , t1.`title`, t1.`message`, t1.`senttime` , t1.`readstatus`, t1.`responded`, t1.`merchanthidden`
FROM `inquiries` as t1
INNER JOIN users as fromData on t1.from_id = fromData.id
INNER JOIN users as toData on t1.to_id = toData.id
INNER JOIN products as prodData on t1.product_id = prodData.id
WHERE t1.id=13
Above query joins 3 tables (inquiries, users, products) together and gets data from each table.
Sometimes it is possible that items in the 'products' table get deleted. Trying to join products table by a deleted product id will fail the query.
Is there a way that I can assign 'prodData.prodname' a default value and execute query without failing in case of a missing item in products table ?
Why don't use left join insted of inner join ,
The LEFT JOIN keyword returns all records from the left table (table1), and the matched records from the right table (table2). The result is NULL from the right side, if there is no match.
SELECT
fromData.name as fromname, toData.name as toName, prodData.prodname,
t1.`from_id`, t1.`to_id` , t1.`product_id` , t1.`title`, t1.`message`, t1.`senttime` , t1.`readstatus`, t1.`responded`, t1.`merchanthidden`
FROM `inquiries` as t1
INNER JOIN users as fromData on t1.from_id = fromData.id
INNER JOIN users as toData on t1.to_id = toData.id
LEFT JOIN products as prodData on t1.product_id = prodData.id
WHERE t1.id=13
Related
I have two tables
Table1: violations
Columns: date, time, pdid, pname, v1, v2, v3, v4
Each v1 through v4 has an integer value which corresponds to a single entry (ID) in table 2.
table2: parking_violations
columns: code, section, description, ID
I need to query each record of violations based on pdid, and match each 'v1-v4' to column 'ID' in the p_violations table.
SELECT
parking.date,
parking.time,
parking.pname,
parking_violations.code,
parking_violations.section,
parking_violations.description
FROM
parking
INNER JOIN parking_violations ON parking.v1=parking_violations.ID
WHERE
pdid=5
This returns the correct records for V1, but I cannot figure out how to also return V2-V4 all populated by matching the value to ID.
Like #fa06 explain, you can use multiple joins to the same table, but instead of inner join i will use left join, this way i have the flexibility of get rows where not all vN have matching IDs on the table parking_violations.
SELECT
parking.date,
parking.time,
parking.pname,
pv1.code,
pv1.section,
pv1.description,
pv2.code,
pv2.section,
pv2.description,
pv3.code,
pv3.section,
pv3.description,
pv4.code,
pv4.section,
pv4.description
FROM
parking
LEFT JOIN
parking_violations AS pv1 ON pv1.ID = parking.v1
LEFT JOIN
parking_violations AS pv2 ON pv2.ID = parking.v2
LEFT JOIN
parking_violations AS pv3 ON pv3.ID = parking.v3
LEFT JOIN
parking_violations AS pv4 ON pv4.ID = parking.v4
WHERE
parking.pdid = 5;
use join multiple time with alias like below:
SELECT
parking.date,
parking.time,
parking.pname,
parking_violations.code,
parking_violations.section,
parking_violations.description
FROM
parking
INNER JOIN parking_violations ON parking.v1=parking_violations.ID
inner join parking_violations a ON parking.v2=a.ID
inner join parking_violations b ON parking.v3=b.ID
inner join parking_violations c ON parking.v4=d.ID
WHERE
pdid=5
I have a query
SELECT DISTINCT c.camp_id AS camp_id,
c.camp_key AS camp_key,
c.camp_active AS camp_active,
c.camp_deleted AS camp_deleted,
c.camp_name AS camp_name,
c.camp_cpc AS camp_cpc,
c.camp_destination AS camp_destination,
camp_token1,
camp_token2,
camp_token3,
camp_token4,
camp_token5,
camp_token6,
camp_token7,
camp_token8,
camp_token9,
camp_token10,
token1_field,
token2_field,
token3_field,
token4_field,
token5_field,
token6_field,
token7_field,
token8_field,
token9_field,
token10_field,
group_name,
group_id,
source_id,
source_name,
user_name
FROM mt_campaigns c
LEFT JOIN mt_offers USING (camp_id)
LEFT JOIN mt_groups USING (group_id)
LEFT JOIN mt_traffic_sources USING (source_id)
LEFT JOIN mt_account WHERE c.owner_id = mt_account.user_id
WHERE camp_deleted=0
Now I want to join another table(mt_account) which has a column called user_id and it matches with the the owner_id column of the mt_canpaigns.
How can i edit the join query?
replace
LEFT JOIN mt_account WHERE c.owner_id=mt_account.user_id
for
LEFT JOIN mt_account ON c.owner_id=mt_account.user_id
You need to use ON to define the fields you want to join on instead of WHERE
I have this query :
SELECT bussiness.bussId , count(favourites.userID) as fav
from `bussiness`
LEFT JOIN `favourites` on (`bussiness`.`bussId` = `favourites`.`bussId`)
where bussiness.bussId= 12310
when I run this query I get fav = 2.
but when I Left join another table ,
SELECT bussiness.bussId , count(favourites.userID) as fav from `bussiness`
LEFT JOIN `favourites` on (`bussiness`.`bussId` = `favourites`.`bussId`)
LEFT JOIN `invoices` on (`bussiness`.`bussId` = `invoices`.`bussId`)
where bussiness.bussId= 12310
I get fav = 88 instead of 2
why this happened ?
It appears as if there are multiple occurrences of bussId in the hello table causing the number of rows returned to multiply. Since you were not doing a distinct count of userID, the query was simply counting the number of rows that contain a userID. If you want to count the number of unique users, you need to use COUNT DISTINCT. Like this:
SELECT bussiness.bussId , count(distinct favourites.userID) as fav from `bussiness`
LEFT JOIN `favourites` on (`bussiness`.`bussId` = `favourites`.`bussId`)
LEFT JOIN `hello` on (`bussiness`.`bussId` = `hello`.`bussId`)
where bussiness.bussId= 12310
I'm trying to make a count within several table with JOIN, but when I made several JOINs the COUNTs got wrongly counted.
Basically I've got 4 tables, named:
predective_search
predective_to_product
predective_to_category
predective_to_manufacturer
I want to count the total number of products, categories and manufacturer which has same id in table predective_search.
Here's my code:
SELECT * ,
COUNT(pp.predictive_id) AS total_products,
COUNT(pc.predictive_id) AS total_categories,
COUNT(pm.predictive_id) AS total_manufacturers
FROM predictive_search ps
LEFT JOIN predictive_to_product pp ON (ps.predictive_id = pp.predictive_id)
LEFT JOIN predictive_to_category pu ON (ps.predictive_id = pc.predictive_id)
LEFT JOIN oc_predictive_to_manufacturer pm ON (ps.predictive_id = pm.predictive_id)
GROUP BY ps.predictive_id
Also the GROUP BY is needed I think. I'm stuck at this as I'm not getting any way to do this
SELECT
ps.*,
agg_pp.total_products,
agg_pc.total_categories,
agg_pm.total_manufacturers
FROM predictive_search ps
LEFT JOIN (
SELECT pp.predictive_id, COUNT(*) AS total_products
FROM predictive_to_product pp
GROUP BY pp.predictive_id
) agg_pp ON ps.predictive_id = agg_pp.predictive_id
LEFT JOIN (
SELECT pc.predictive_id, COUNT(*) AS total_categories
FROM predictive_to_category pc
GROUP BY pc.predictive_id
) agg_pc ON ps.predictive_id = agg_pc.predictive_id
LEFT JOIN (
SELECT pm.predictive_id, COUNT(*) AS total_manufacturers
FROM predictive_to_category pm
GROUP BY pm.predictive_id
) agg_pm ON ps.predictive_id = agg_pm.predictive_id
I have a situation where a property table holds an address id (from the g_addresses table) and an applicant table also holds an address id from the g_addresses.
I'd like to left join these together but select all the fields in the table.
I know of using 'as' to make an alias for fields, but is there any way to produce an alias for a whole table?
SELECT *
FROM (`reference`)
LEFT JOIN `applicants` ON `applicants`.`id` = `reference`.`applicant_id`
LEFT JOIN `g_people` applicant_person ON `applicant_person`.`id` = `applicants`.`person_id`
LEFT JOIN `g_addresses` applicant_address ON `applicant_address`.`id` = `applicants`.`address_id`
LEFT JOIN `properties` ON `properties`.`id` = `reference`.`property_id`
LEFT JOIN `g_addresses` property_address ON `property_address`.`id` = `properties`.`address_id`
WHERE `reference`.`id` = 4
This produces a result containing only one address row and not both,
The row that is returned is the row from the final join and not the one previously, indicating it is overwriting when it is returned.
I don't think you should use masked references, like * or `reference`.*, in your case, because you may end up with a row set containing identical column names (id, address_id).
If you want to pull all the columns from the joined tables, you should probably specify them individually in the SELECT clause and assign a unique alias to every one of them:
SELECT
ref.`id` AS ref_id,
ref.`…` AS …,
…
app.`id` AS app_id,
…
FROM `reference` AS ref
LEFT JOIN `applicants` AS app ON app.`id` = ref.`applicant_id`
LEFT JOIN `g_people` AS ape ON ape.`id` = app.`person_id`
LEFT JOIN `g_addresses` AS apa ON apa.`id` = app.`address_id`
LEFT JOIN `properties` AS pro ON pro.`id` = ref.`property_id`
LEFT JOIN `g_addresses` AS pra ON pra.`id` = pro.`address_id`
WHERE ref.`id` = 4
Be more specific about columns you select
SELECT
applicant_address.*,
property_address.*,
applicants.*,
applicant_person.*,
properties.*
FROM (`reference`)
LEFT JOIN `applicants` ON `applicants`.`id` = `reference`.`applicant_id`
LEFT JOIN `g_people` applicant_person ON `applicant_person`.`id` = `applicants`.`person_id`
LEFT JOIN `g_addresses` applicant_address ON `applicant_address`.`id` = `applicants`.`address_id`
LEFT JOIN `properties` ON `properties`.`id` = `reference`.`property_id`
LEFT JOIN `g_addresses` property_address ON `property_address`.`id` = `properties`.`address_id`
WHERE `reference`.`id` = 4