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?
Related
I'm having difficult with the logic/syntax surrounding a nested 'select max(date)' style statement. Let me try to explain. I have three tables that my statement is pulling data from:
Table #1 (table1_companies)
[id, companyname, industry]
Table #2: (table2_companydata)
[id, companyname, data, date_added]
Table #3: (table3_watchlist)
[id, companyname, usernane]
The statement I'm attempting to execute takes a company name from the Table 3, INNER JOINS the 'industry' from Table 1 and then INNER JOINS the latest company info (based on the last date) from Table 2. It is Table 2 that can have many rows per company, I just need the last one based on the latest date that was added. My current (simplified) statement without the attempt to grab the last date is:
SELECT
table1_companies.industry,
table2_companydata.data,
table3_watchlist.*
FROM
table3_watchlist
INNER JOIN table1_companies ON table1_companies.companyname = table3_watchlist.companyname INNER JOIN table2_companydata ON table2_companydata.companyname = table3_watchlist.companyname WHERE username='username'");
I think I need to insert a "SELECT max(date_added) FROM table2_companydata" into the 2nd INNER JOIN. But I've had no success with either logic or syntax. Can any enlighten me?
Do the joins and then select the last record. Here is one method using a where clause for the logic:
SELECT c.industry, cd.data, w.*
FROM table3_watchlist w INNER JOIN
table1_companies c
ON c.companyname = w.companyname INNER JOIN
table2_companydata cd
ON cd.companyname = w.companyname
WHERE username = 'username' AND
cd.date_added = (select max(cd2.date_added)
from table2_companydata cd2
where cd2.companyname = cd.companyname
);
So after helpful feedback from my original question, I now have this query:
SELECT sessions.id, sessions.title, sessions.abstract, sessions.presenters, sessions.proposal_id, proposals.outcomes, proposals.CategorySelection, proposals.research3, proposals.research4, proposals.research5, proposals.research6, proposals.innovation3, proposals.innovation4, proposals.innovation5,proposals.innovation6, proposals.application3, proposals.application4, proposals.application5, proposals.application6, proposals.integration3, proposals.integration4, proposals.integration5, proposals.integration6, proposals.references, proposals.organization
FROM sessions, proposals
INNER JOIN proposals ON proposals.id = sessions.proposal_id
WHERE sessions.id = '$id
LIMIT 1;)
that is getting me nowhere fast. What am I doing wrong?
Original question:
I need to pull several fields from one table and several more from a second table. The criteria is that a field called proposal_id match the id field of the second table. I am fairly new so this is what I have so far. It is not working, but not sure how to make it work.
(SELECT `title`,`abstract`,`presenters`,`proposal_id` FROM `sessions` WHERE `id`='$id')
UNION
(SELECT `outcomes`,`CategorySelection`,`research3`,`research4`,`research5`,`research6`,`innovation3`,`innovation4`,`innovation5`,
`innovation6`,`application3`,`application4`,`application5`,`application6`,`integration3`,`integration4`,`integration5`,`integration6`,`references`,`organization` FROM `proposals` WHERE `id`= `sessions`.`proposal_id`)
LIMIT 1;
You need to use JOIN not UNION
select
s.*,p.*
from `sessions` s
inner join `proposals` p on p.id = s.proposal_id
where s.id = '$id'
This is how you can join both the tables using the common key between.
You can select the specific fields instead of .* by specifying the column names as
s.col1,s.col2,p.col1,p.col2
etc
Try to use JOINS, where you can match the related fields from both the tables , this is the most convenient way to fetch records from multiple tables
UNION is used when you want to combine two queries
select a.id,b.some_field from table1 as a
INNER JOIN table2 as b ON b.prospal_id = a.id
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'
I'm using an opensource database, so it's setup is a bit over my head.
Its basically like this.
A persons normal information is in the table 'person_per'
There is custom information in the table 'person_custom'
both use 'per_ID' to organize.
select per_ID from person_custom where c3 like '2';
gives my the IDs of people who fit my search, I want to "join" (I think) their name, phone, ect from the 'person_per' table using the ID as the "key"(terms I read that seem to fit).
How can I do that in a single query?
select per.*
from person_per per
inner join person_custom cus on cus.per_id = per.per_id
where cus.c3 = 2
You can retrieve all the columns from both tables with a single query:
SELECT p.name
, p.phone
, p.ect
, c.custom_col
FROM person_per p
JOIN person_custom c
ON c.per_ID = p.per_ID
WHERE c.c3 LIKE '2'
Use a JOIN operator between the table names, and include the "matching" criteria (predicate) in the ON clause.
I am having trouble with my database. I have three corresponding tables, where I in the first is holding some pages and in the second one holding some fields.
The third one is a table holding content to all fields in the pages.
Tables:
pages(PageID, Name)
fields(FieldID, FieldName);
pagefields(PageFieldID, FieldID, PageID)
pagefieldcontents(PageFieldContentID, PageFieldID, FieldID, PageID, Content)
What I need is to make sure, that EVEN if there in the table "pagefields" is NO value to a field, but if the field is related to the page (in the pagefields table), it will get returned as a row with value as an empty string.
What I am doing now is the following:
SELECT
pfc.ContentID as PFC_ContentID,
pfc.Content as PFC_FieldContent,
pfc.FieldID as PFC_FieldID
FROM
pagesfieldcontents pfc
INNER JOIN
pagefields pf
ON pf.PageID = pfc.PageID
INNER JOIN
fields ptf
ON pf.FieldID = ptf.FieldID
INNER JOIN
pages p
ON p.PageID = pf.PageID
WHERE
(some where-statement)
ORDER BY
somefield desc
Hope you can understand my question - have a nice day.
INNER JOINs require there to be a row in the joined table for the first tabke's row to be returned. But you may have fields that font have content and you shill want those returned...
Change all your INNER joins to LEFT joins:
SELECT
pfc.ContentID as PFC_ContentID,
pfc.Content as PFC_FieldContent,
pfc.FieldID as PFC_FieldID
FROM pages p
LEFT JOIN pagefields pf
ON p.PageID = pf.PageID
LEFT JOIN fields ptf
ON pf.FieldID = ptf.FieldID
LEFT JOIN pagesfieldcontents pfc
ON p.PageID = pfc.PageID
AND pf.FieldID = pfc.FieldID
WHERE some where-statement
ORDER BY somefield desc
I've also rearranged the table order and join conditions to what I guess you need.