I have the following query in my application:
SELECT
p.old_product_id,
l.product_id,
p.sku,
p.title,
p.option_one,
p.option_two,
FROM
lookup_id l
JOIN temp_price_tables_data p USING (sku);
And it works great. However, a small percentage of records from the temp_price_tables_data tables don't make it to the results.
This is because the skus from the lookup_id table don't exist in the temp_price_tables_data.
Is there a way to keep these records in the new data?
Or is there a way to only get those records so I can store the result for later processing?
EDIT:
First table columns = old_product_id, sku, title, option_one, option_two
Second table column = product_id, sku
Tables should have SKU in common.
Use a left outer join:
SELECT
*
FROM
lookup_id l
LEFT OUTER JOIN price_tables_data p on l.sku = p.sku
WHERE old_product_id IS NULL;
That will get you all the records that are in temp_price_tables_data but not in lookup_id
Related
I have the following query:
SELECT
usp.user_id AS userId,
usp.create_time AS create_time,
ml.amount AS amount
FROM user_subscription_plan AS usp
RIGHT JOIN product AS product ON product.id = usp.product_id
LEFT JOIN modification_log AS ml ON ml.subscription_id = usp.id
WHERE usp.id IN ('447482')
I have three tables, from which I need to select data.
My problem begins with the last LEFT join.
modification_log table could have no entries, but also it could have more entries.
I want to select only the latest entry. With the above query, if I have 2 (or more) entries in the modification_log, I receive 2 identical results (repeated).
What I would like to get:
If there are no results in the modification_log, then it will return null. I think that is covered with LEFT JOIN. But also, in the case of many record, I would need to select the latest added one (amount)
I believe I might need a sub-query, but I fail to implement it.
You have to use a subquery for taking left join with modification_log table as
SELECT
usp.user_id AS userId,
usp.create_time AS create_time,
ml.amount AS amount
FROM user_subscription_plan AS usp
RIGHT JOIN product AS product ON product.id = usp.product_id
LEFT JOIN
(select * modification_log where subscription_id
IN ('447482') order by created_at desc LIMIT 1)
AS ml ON ml.subscription_id = usp.id
WHERE usp.id IN ('447482')
Note that the where clause in subquery select * modification_log where subscription_id IN ('447482')
is the same as with the last where condition
Just add a max condition after your left join to get the latest entry to be joined, like below-
LEFT JOIN modification_log AS ml ON ml.subscription_id = usp.id
where usp.id IN ('447482') and ml.id = (select max(id) from modification_log)
I have SQL like below:
SELECT
p1.*
FROM
payment p1
INNER JOIN (
SELECT
p2.contract_id_fk,
MAX(p2.payment_id_pk) AS maxpay
FROM
payment p2
GROUP BY
p2.contract_id_fk) p2
ON (
p1.payment_id_pk = p2.maxpay)
LEFT JOIN
contracts c
ON (
c.contract_id_pk = p1.contract_id_fk)
WHERE
p1.contract_id_fk != 0
AND
p1.payment_remain=0;
The first join is to get the last record when I use group by
my problem is in the second join. It doesn't get the data from the second table named contracts.
The result is the right record that I need but without the data from the second joined table.
You've only asked for the first table. SELECT p1.* You need to include whatever fields you need from the second table in the select, ie select p1.*, p2.*
Having 5 tables
Table a_dates = id,
Table b_types = id, a_date_id, c_type_id,
Table c_types = id, name,
Table d_profiles = id, name, profile_type
Table e_ps = id, a_date_id, d_profile_id
From a_dates Need to get b_types,...then from b_types needs c_types name,... Then compare c_types name with d_profiles name and get d_profiles id.... if equals then create a records in e_ps with a_date_id, d_profile_id.
Could any one please help me in getting the query from inner join.
I tried like, it is incomplete query
INSERT INTO e_ps(id,a_date_id,a_date_type,d_profile_id,c_id)
SELECT '',a.id,'A',dp.id,'67' FROM d_profiles dp
INNER JOIN a_dates a ON {HERE I NEED NAME MATCHING WITH c_types name} = dp.name and dp.profile_type = 'A'
INNER JOIN a_dates ON a.id = a_dates.id
LEFT OUTER JOIN e_ps eps ON eps.a_date_type = 'A' AND eps.a_date_id = a_dates.id
WHERE eps.a_date_id IS NULL
This seems to be a relatively simple JOIN:-
INSERT INTO e_ps(id, a_date_id, d_profile_id)
SELECT NULL, a_dates.id, d_profiles.id
FROM a_dates
INNER JOIN b_types ON a_dates.id = b_types.a_date_id
INNER JOIN c_types ON b.c_type_id = c.id
INNER JOIN d_profiles ON c_types.name = d_profiles.name
With joins there are several types, and I suspect you are getting confused. Briefly:-
With an INNER JOIN it looks for a match that is on BOTH tables. If no
match the no record is returned.
With a LEFT OUTER JOIN it takes a record from the table on the left
and looks for a match on the table on the right. If a match great,
but if not then it still brings a row back but the columns from the
table on the right just have values of NULL.
A RIGHT OUTER JOIN is very much the same, just with the tables
reversed (most people including me avoid using this as it has no
advantages most of the time but just makes things confusing).
With a FULL OUTER JOIN it gets the records from both side, whether
they match or not. If they match then the columns from both are
returned, if not matched then the columns from one are returned. Not
that MySQL does not support a FULL OUTER JOIN (although there are
ways to emulate it).
A CROSS JOIN joins every combination of 2 tables. These are used when
there is no common column to match on but you want all combinations.
For example if you wanted a table of all employees and all days of
the week for each employee you would cross join a table of days of
the week against a table of employees (then for useful data you might
LEFT OUTER JOIN a table of holidays to the result).
I have the following query:
SELECT
dashboard_data.headline,
dashboard_data.message,
dashboard_messages.image_id
FROM dashboard_data
INNER JOIN dashboard_messages
ON dashboard_message_id = dashboard_messages.id
So I am using an INNER JOIN and grabbing the image_id. So now, I want to take that image_id and turn it into images.filename from the images table.
How can I add that in to my query?
You can simply add another join like this:
SELECT dashboard_data.headline, dashboard_data.message, dashboard_messages.image_id, images.filename
FROM dashboard_data
INNER JOIN dashboard_messages
ON dashboard_message_id = dashboard_messages.id
INNER JOIN images
ON dashboard_messages.image_id = images.image_id
However be aware that, because it is an INNER JOIN, if you have a message without an image, the entire row will be skipped. If this is a possibility, you may want to do a LEFT OUTER JOIN which will return all your dashboard messages and an image_filename only if one exists (otherwise you'll get a null)
SELECT dashboard_data.headline, dashboard_data.message, dashboard_messages.image_id, images.filename
FROM dashboard_data
INNER JOIN dashboard_messages
ON dashboard_message_id = dashboard_messages.id
LEFT OUTER JOIN images
ON dashboard_messages.image_id = images.image_id
Just add another join:
SELECT dashboard_data.headline,
dashboard_data.message,
dashboard_messages.image_id,
images.filename
FROM dashboard_data
INNER JOIN dashboard_messages
ON dashboard_message_id = dashboard_messages.id
INNER JOIN images
ON dashboard_messages.image_id = images.image_id
I shared my experience of using two LEFT JOINS in a single SQL query.
I have 3 tables:
Table 1) Patient consists columns PatientID, PatientName
Table 2) Appointment consists columns AppointmentID, AppointmentDateTime, PatientID, DoctorID
Table 3) Doctor consists columns DoctorID, DoctorName
Query:
SELECT Patient.patientname, AppointmentDateTime, Doctor.doctorname
FROM Appointment
LEFT JOIN Doctor ON Appointment.doctorid = Doctor.doctorId //have doctorId column common
LEFT JOIN Patient ON Appointment.PatientId = Patient.PatientId //have patientid column common
WHERE Doctor.Doctorname LIKE 'varun%' // setting doctor name by using LIKE
AND Appointment.AppointmentDateTime BETWEEN '1/16/2001' AND '9/9/2014' //comparison b/w dates
ORDER BY AppointmentDateTime ASC; // getting data as ascending order
I wrote the solution to get date format like "mm/dd/yy" (under my name "VARUN TEJ REDDY")
Multi joins in SQL work by progressively creating derived tables one after the other.
See this link explaining the process:
https://www.interfacett.com/blogs/multiple-joins-work-just-like-single-joins/
I have a table called "orders" with
order_id
customer_name
item
and am joining it to another table called "orders_requests" containing
order_id
requests
One row in "orders" may have zero or more rows in "order_requests." I'm trying to perform a query to find "orders" that have "orders_requests" of "rush processing" and "free shipping." I'm leaning towards a RIGHT OUTER JOIN with the "orders_requests" table on the left so it only returns results if a corresponding "orders" row exists, but I've had no success with either of these queries.
This one doesn't work since it pulls rows that are rush processing or free shipping.
SELECT DISTINCT orders.order_id, orders.* ,
FROM orders_requests
RIGHT OUTER JOIN orders ON orders_requests.order_id = orders.order_id
WHERE orders_requests.requests
IN ('rush processing', 'free shipping')
And this one clearly doesn't work since it's impossible for any one row to match both conditions.
SELECT DISTINCT orders.order_id, orders.* ,
FROM orders_requests
RIGHT OUTER JOIN orders ON orders_requests.order_id = orders.order_id
WHERE orders_requests.requests = 'rush processing'
AND orders_requests.requests = 'free shipping'
Is what I'm trying to do possible with my table setup do I need to change the structure?
I am not sure if this would work since I cannot test it atm but try this:
select a.order_id, b.*, c.*
from orders a
left outer join orders_requests b on b.order_id = a.order_id
left outer join orders_requests c on c.order_id = a.order_id
where b.requests = 'rush processing' and c.requests = 'free shipping'