Using Joins To Retrieve Data Twice - php

I have the following two MySQL queries.
$delivery_id =
select c.countries_id
from orders o
LEFT JOIN countries c
ON c.countries_name = o.delivery_country
where o.orders_id = 1208;
$billing_id =
select c.countries_id
from orders o
LEFT JOIN countries c
ON c.countries_name = o.billing_country
where o.orders_id = 1208;
With the results being put into the variables (PHP) as appropriate. What I would like to know is, is there a way to combine these two queries into one singular query instead of running it twice. (This is using ZenCart's Query Factory ($db->Execute) where the results will be put into a fields array and recalled as such.
Info about the tables: Each order in orders will contain a billing and delivery address with a country name being found in the appropriate field (billing_country and delivery_country). However, not all orders will contain a delivery address. How can I combine these two into one query? I know that I can use a LEFT JOIN of some sort but am not sure on how to write it.

You can join the countries table two times using different alias names:
select
c1.countries_id AS delivering_id,
c2.countries_id AS billing_id
from orders o
LEFT JOIN countries c1
ON c1.countries_name = o.delivery_country
LEFT JOIN countries c2
ON c2.countries_name = o.billing_country
where o.orders_id = 1208;

Use union operator as ,
select c.countries_id
from orders o
LEFT JOIN countries c
ON c.countries_name = o.delivery_country
where o.orders_id = 1208
UNION
select c.countries_id
from orders o
LEFT JOIN countries c
ON c.countries_name = o.billing_country
where o.orders_id = 1208;

Related

MySQL Inner Join, selecting from multiple tables

I'm really struggling to get my head around this. I am trying to run a SELECT query from multiple tables.
This is what I have so far that doesn't work;
SELECT jira_issues.*, session_set.* FROM jira_issues, session_set
INNER JOIN reports on jira_issues.report_id = reports.id
WHERE jira_issues.report_id = 648
I have other tables (session_set, report_device) which has a ReportID and report_id column respectively.
I have a report table which has a Primary Key id. In the other tables the report.id key is linked with foreign keys.
Ultimately what I am trying to achieve is this:
I have an entry in the reports table with an id of 648. In the other tables (jira_issues, report_device, session_set), I also have entries which has a foreign key linked to the report id in the report table.
I want to run one SELECT Query to query the tables (jira_issues, report_device and session_set) and get all the data from them based on the report.id.
Thanks!
What about this:
SELECT * FROM jira_issues ji
LEFT JOIN session_set ss ON ji.report_id = ss.ReportID
LEFT JOIN report_device rd ON rd.report_id = ji.report_id
WHERE ji.report_id = 648;
Just say "no" to commas in the from clause. Always use explicit join syntax:
SELECT ji.*, session_set.*
FROM jira_issues ji inner join
reports r
on ji.report_id = r.id inner join
session_set ss
on ss.ReportId = r.report_id
WHERE ji.report_id = 648;
If some of the tables might have no corresponding rows, you might want left outer join instead of inner join.
Kindly try this out. You may get syntax error.
SELECT a., b. FROM jira_issues a, session_set b, reports c
Where a.report_id = c.id and b.report_id = c.id AND a.report_id = 648

Search keyword and apply filters

I am encountering a problem I cannot bypass by myself and I that's why I am posting this question. There are a lot of other posts out there that give me half of the answer and I don't really know how to get it done.
I have 3 tables that contain informations about an ad. One table is "ad_names", another is "ad_locations" and the last one is "ad_details".
Ad_Names has : ad_title, ad_description, ad_date_added
Ad_Locations has : ad_country, ad_region, ad_city
Ad_Details has : ad_price, ad_author, ad_active
Basically I want apply location and details filters for an ad with a certain title.
For example, I want to search "food" keyword in ad-titles and then apply filters like "only from Kansas" or "Only from Kansas + price higher than 500USD". How do I do it?
first you will need to join the tables. do you know if you have a foreign key on the tables? like is there an Ad_ID field on all 3 tables? if the tables are large you may also want to index the fields you are searching. once you have all the data you will "filter" it with a where clause.
http://www.w3schools.com/sql/sql_where.asp
select * from ad_names as A
join ad_location as L on A.key=L.key
join ad_details as D on A.key=D.key
where A.ad_title like '%food%' and L.ad_region = 'Kansas' and D.ad_prics > 500;
depending on how your database is setup, you may get a cartesian result there, so you would have to look at your join. maybe a left outer join limiting the join in an on statement instead of in the where. it is hard to say without more information.
Join types
Assuming that Ad is a table with primary key id, which is a foreign key in each of the other tables (ad_id) then something along the lines of:
Location:
SELECT *
FROM Ad A
INNER JOIN Ad_Names N ON N.ad_id = A.id
INNER JOIN Ad_Locations L ON L.ad_id = A.id
INNER JOIN Ad_Details D ON D.ad_id = A.id
WHERE N.ad_title LIKE '%food%' AND L.ad_city = 'Kansas'
Price and location:
SELECT *
FROM Ad A
INNER JOIN Ad_Names N ON N.ad_id = A.id
INNER JOIN Ad_Locations L ON L.ad_id = A.id
INNER JOIN Ad_Details D ON D.ad_id = A.id
WHERE N.ad_title LIKE '%food%' AND L.ad_city = 'Kansas' AND D.ad_price > 500

MySQL Join for newsletters

I have a problem with mysql query. I am sending newsletters.
My mysql schema looks like to follwing http://sqlfiddle.com/#!2/178b7/18
How am I suppose to get from the database the COUNT of the mails that will be send.
For every List_ID in LISTS TAKE every base_id from lists_mailbases, and then count all of the base_id that are in email_database.
For example in my schema list1 should have 4 recipients, list 2 should have 2 recipients.
I wrote something like this:
SELECT l.id, COUNT(*) FROM lists l
JOIN lists_mailbases lm ON l.id = lm.list_id
JOIN email_database ed ON ed.base_id = lm.base_id
GROUP BY l.id;
but as a result, I have almost twice more results i should have. (on sqlfiddle it is ok but in my main database where i have a lot of records it gives me wrong data)
As you said, you are getting twice as much as you expect, it looks like one of the joins produces more than one record for the join. Diagnose that out.
SELECT ID, COUNT(*)
FROM
(
SELECT l.id, ED.BASE_ID FROM lists l
JOIN lists_mailbases lm ON l.id = lm.list_id
JOIN email_database ed ON ed.base_id = lm.base_id
GROUP BY l.id, ED.BASE_ID
) A;
nice question with SQLFiddle!
just add ed.base_id to your GROUP BY
SELECT l.id,ed.base_id, COUNT(*) , GROUP_CONCAT(ed.email)
FROM lists l JOIN lists_mailbases lm ON l.id = lm.list_id
JOIN email_database ed ON ed.base_id = lm.base_id
GROUP BY l.id,ed.base_id;
your lists_mailbases has repeated data by the way, it has 2 rows with the same base_id.
if your data is correct and you want to count DISTINCT base_id, just do COUNT(DISTINCT base_id)
like below
SELECT l.id, COUNT(DISTINCT ed.base_id) , GROUP_CONCAT(ed.email)
FROM lists l JOIN lists_mailbases lm ON l.id = lm.list_id
JOIN email_database ed ON ed.base_id = lm.base_id
GROUP BY l.id;

mysql query dont gets all posts

I have a MYSQL query who have to list all post i want it to post. But it dont do it. It shows posts when i have more then one post in the table "meaOrder" with the same "ordCode". But when i have only on post in meaOrder, i don't show it. What can i do?
SELECT koden, wish, rnamn, bild, pris, cname, onsktext
FROM (
SELECT m.wishText as onsktext, m.meaOID as midn, m.ordcode as koden, w.wish as wish, r.meaName as rnamn, r.meaImg as bild,
r.meaPrice as pris, k.catName as cname from cats k, meals r, wishes w,
meaOrder m
join orders c on c.ordNR=4401
WHERE c.ordStatus=1 AND m.ordNR=c.ordNR AND m.meaID=r.meaID AND m.wishesID=w.id
AND r.catID=k.catID
) T
GROUP BY koden, rnamn, bild, pris, cname
ORDER BY midn DESC
TABLE orders
http://grab.by/m74E
TABLE meaOrder http://grab.by/m74Q
Try replacing the JOIN with RIGHT JOIN in this case. The difference is explained at JOIN Syntax page in MySQL docs . In short - JOIN returns row only if there are corresponding rows in both joined tables (inner join). LEFT JOIN / RIGHT JOIN return all rows from one of the tables and corresponding row if it exists from the other table (those are outer joins)
Do you need a subselect?
This seems to cover it:-
SELECT m.ordcode AS koden, w.wish AS wish, r.meaName AS rnamn, r.meaImg AS bild, r.meaPrice AS pris, k.catName AS cname, m.wishText AS onsktext
FROM cats k
INNER JOIN meals r ON r.catID = k.catID
INNER JOIN meaOrder m ON m.meaID = r.meaID
INNER JOIN wishes w ON m.wishesID = w.id
INNER JOIN orders c ON m.ordNR = c.ordNR
WHERE c.ordStatus = 1
AND c.ordNR = 4401
GROUP BY m.ordcode, r.meaName, r.meaImg, r.meaPrice, k.catName
ORDER BY midn DESC

Performing a join on ZenCart's address book entries

I have the following bits of code:
$referrers_query =
select c.customers_id, c.customers_firstname, c.customers_lastname,
c.customers_email_address, c.customers_telephone, a.entry_street_address,
a.entry_city, a.entry_state, a.entry_country_id, n.countries_name,
a.entry_zone_id, a.entry_postcode, r.referrer_customers_id,
r.referrer_key, r.referrer_homepage, r.referrer_approved,
r.referrer_banned, r.referrer_commission from customers as c,
address_book as a, referrers as r, countries as n
where a.entry_country_id = n.countries_id and c.customers_id = r.referrer_customers_id
and a.address_book_id = c.customers_default_address_id order by c.customers_lastname;
What I would like to do, is instead of making a WHERE clause join, I'd like to nest the joins.
There are five database tables noted above.
customers, address_book, referrers, countries, zones.
But I have no idea where to get started. The main problem with this is using the above statement, I seem to lose a few records from the select. This is because some records are using a 'zone_id' = 0. A fix to this was to simply create a blank record for 0 but besides that, can I use a join to fix this?
The query written with explicit JOINs:
SELECT c.customers_id, c.customers_firstname, c.customers_lastname,
c.customers_email_address, c.customers_telephone, a.entry_street_address,
a.entry_city, a.entry_state, a.entry_country_id, n.countries_name,
a.entry_zone_id, a.entry_postcode, r.referrer_customers_id,
r.referrer_key, r.referrer_homepage, r.referrer_approved,
r.referrer_banned, r.referrer_commission
FROM customers AS c
JOIN referrers AS r ON (c.customers_id = r.referrer_customers_id)
JOIN address_book AS a ON (a.address_book_id = c.customers_default_address_id)
JOIN countries AS n ON (a.entry_country_id = n.countries_id)
ORDER BY c.customers_lastname
If you want to also get the info from the zones table if a match exists, you would need to add a LEFT JOIN like this:
SELECT c.customers_id, c.customers_firstname, c.customers_lastname,
c.customers_email_address, c.customers_telephone, a.entry_street_address,
a.entry_city, a.entry_state, a.entry_country_id, n.countries_name,
a.entry_zone_id, a.entry_postcode, r.referrer_customers_id,
r.referrer_key, r.referrer_homepage, r.referrer_approved,
r.referrer_banned, r.referrer_commission
FROM customers AS c
JOIN referrers AS r ON (c.customers_id = r.referrer_customers_id)
JOIN address_book AS a ON (a.address_book_id = c.customers_default_address_id)
JOIN countries AS n ON (a.entry_country_id = n.countries_id)
LEFT JOIN {zones table name} AS z ON (z.{zones id column name} = a.entry_zone_id)
ORDER BY c.customers_lastname
and also add the columns you want to select to the top of the query. A LEFT JOIN always returns a result from the left table (first one listed) and if there is no match in the right table, it returns NULLs for the right table's columns.

Categories