I have 3 tables, as follows:
Patron
======
patron_num
Booking_For_Schedule
====================
tname
date
time
booking_num
Booking_By_Patron
=================
booking_num
patron_num
I would like to retrieve a result with columns patron_num, date, time, and tname, like so:
patron_num date time tname
1 2013-11-03 20:00 TestName
...etc
The purpose of this homework question is to teach us INNER JOINS, but I am having some difficulty. Could some kind SO user push me in the right direction?
Here's my SQL:
SELECT `patron_num`,`date`,`time`,`tname`
FROM `booking_for_schedule` `F`
INNER JOIN `booking_by_patron` `B` on `F`.`booking_num` = `B`.`booking_num`
INNER JOIN `patron` `P` on `B`.`patron_num`=`P`.`patron_num`
which returns the error: #1052 - Column 'patron_num' in field list is ambiguous
SELECT `P`.`patron_num`,`date`,`time`,`tname`
FROM `booking_for_schedule` `F`
INNER JOIN `booking_by_patron` `B` on `F`.`booking_num` = `B`.`booking_num`
INNER JOIN `patron` `P` on `B`.`patron_num`=`P`.`patron_num`
Will help with the ambiguity.
Since patron_num is in multiple tables you need to specify which one you want to use. You can do this by adding the table alias before it like you are in your joins. Example:
SELECT `B`.`patron_num`,`date`,`time`,`tname`
FROM `booking_for_schedule` `F`
INNER JOIN `booking_by_patron` `B` on `F`.`booking_num` = `B`.`booking_num`
INNER JOIN `patron` `P` on `B`.`patron_num`=`P`.`patron_num`
Related
Hi I have two tables and for the same contact "email" in the two tables, I want to know the first time the "email" gets in touch.
conversation_and_id
contact
Expected output
So far I only have done outer join to join the two tables, but it removed duplicated "email", which I need it to compare time difference from the same "email".
ALTER TABLE conversation_and_id CHANGE `email` `conversation_and_id_email` VARCHAR(100);
create table conversation_and_id_and_contact
SELECT *
FROM contact AS con
LEFT JOIN conversation_and_id AS ci ON con.email = ci.conversation_and_id_email
UNION
SELECT *
FROM contact AS con
RIGHT JOIN conversation_and_id AS ci ON con.email = ci.conversation_and_id_email;
create table final
select
if (f.email is not null, f.email, f.conversation_and_id_email) as email1,
if (f.atlas_interest is not null, f.atlas_interest, f.created_at) as time1,
if (f.conversation_and_id_email is not null, f.conversation_and_id_email, f.email) as email2,
if (f.created_at is not null, f.created_at, f.atlas_interest) as time2
from conversation_and_id_and_contact f;
The standard solution everywhere is to perform a full outer join with both tables and get the MIN() timestamp.
However, since MySQL does not (yet) support full outer joins you'll need to union a left and right joins to get the result you want. The final [unnecessarily long] query looks like:
select
coalesce(iemail, cemail) as email,
least(created_at, atlas_interest) as expressed_interest_at
from (
select -- this is the left join
i.email as iemail, i.created_at, c.email as cemail, c.atlas_interest
from conversation_and_id i
left join contact c on c.email = i.email
union
select -- this is the right join
i.email as iemail, i.created_at, c.email as cemail, c.atlas_interest
from conversation_and_id i
right join contact c on c.email = i.email
) x
I am having trouble with a new IMDB like system I'm building. My specific issue is that when I run:
CREATE VIEW `directors` AS
SELECT
`stars`.`id` AS `movie_id`,
`stars`.`title`,`stars`.`rating`,
`stars`.`storyline`,
`stars`.`star`,
`people_list`.`name` AS `director`
FROM `stars`
INNER JOIN `stars`
ON `movie_directors`.`movie` = `stars`.`id`
INNER JOIN `people_list`
ON `movie_directors`.`director` = `people_list`.`id`
WHERE `movie_directors`.`enabled` = 1;
I get the following error:
#1052 - Column 'stars.id' in field list is ambiguous
All of the questions I've found on here seem to relate to when you don't prefix the column name with a table name or, in this case, a view name since I'm writing a view to build off another view
You are selecting from stars and then INNER JOINing on stars:
SELECT ... FROM stars INNER JOIN stars
I think that you probably want to join with movie_directors based on your query.
You are using a self join (starts table is used two time) in this case you need an alias for refer the proper table instance
CREATE VIEW `directors` AS
SELECT
`stars`.`id` AS `movie_id`
, `stars`.`title`
,`stars`.`rating`
, `stars`.`storyline`
, `stars`.`star`
, `people_list`.`name` AS `director`
FROM `stars`
INNER JOIN `stars` as s2 ON `movie_directors`.`movie` = s2.`id`
INNER JOIN `people_list` ON `movie_directors`.`director` = `people_list`.`id`
WHERE `movie_directors`.`enabled` = 1;
I think it's because you are not aliasing correctly.
It should be something like
select ...
from stars
inner join stars as anothername
It looks to be ambiguous because you have two references to the stars table. Your FROM clause and your first INNER JOIN.
It looks like you are intending to join on movie_directors instead of INNER JOIN stars clause. E.g.
CREATE VIEW `directors` AS SELECT
`stars`.`id` AS `movie_id`,
`stars`.`title`,`stars`.`rating`, `stars`.`storyline`, `stars`.`star`, `people_list`.`name` AS `director`
FROM `stars`
INNER JOIN `movie_directors` ON `movie_directors`.`movie` = `stars`.`id`
INNER JOIN `people_list` ON `movie_directors`.`director` = `people_list`.`id` WHERE `movie_directors`.`enabled` = 1;
Hope this helps!
I need to get rows out from article and users table when the slug appears in my highlight table.
Highlight Table
id | slug
1 blue
2 green
Article Table
id | slug | title
1 blue
2 pink
User Table
id | slug | name
1 blue
2 green
3 brown
Heres my query:
SELECT slug from highlight_table
INNER JOIN article_table ON highlight_table.slug = article_table.slug
INNER JOIN user_table ON highlight_table.slug = user_table.slug
I would hope to get id 1 from article table and id 1 and 2 from users table.
The issue is Im getting nothing back from the query.
The query has an error because your SELECT slug is ambiguous. Your column slug appears in all of your tables so MySQL doesn't know which column to return. You need to do
SELECT `highlight_table`.`slug` from `highlight_table`
This will tell MySQL to only return the slug column from the highlight_table.
You should then only get 1 row which is blue, because blue exists in all three tables. Changing to LEFT JOIN for both article and user tables would get you 2 results back (green and blue) as INNER JOIN basically works as an AND and LEFT JOIN works more like an OR
Update!
Based on the final lot of information here is a query that does work:
SELECT highlight.slug from highlight
LEFT JOIN article ON highlight.slug = article.slug
LEFT JOIN user ON highlight.slug = user.slug
WHERE
article.slug IS NOT NULL OR user.slug IS NOT NULL
Another example of doing this:
SELECT `highlight`.`slug` from `highlight`
WHERE `highlight`.`slug` IN (SELECT `user`.`slug` FROM `user` UNION SELECT `article`.`slug` FROM `article`)
OR
SELECT `highlight`.`slug` from `highlight`
INNER JOIN (SELECT `user`.`slug` FROM `user` UNION SELECT `article`.`slug` FROM `article`) AS `allslugs` ON `highlight`.`slug` = `allslugs`.`slug`
Another update, I call this one "fun with joins"
SELECT `highlight`.`slug` from `highlight`
RIGHT JOIN `user` ON `highlight`.`slug` = `user`.`slug`
LEFT JOIN `article` ON `highlight`.`slug` = `article`.`slug`
WHERE
`highlight`.`slug` IS NOT NULL
Try changing your query to qualify the column name in select list
SELECT h.`slug` from HighlightTable h
INNER JOIN ArticleTable a ON h.`slug` = a.`slug`
INNER JOIN UserTable u ON h.`slug` = u.`slug`;
Can't reproduce the issue. See This Fiddle
per your latest comment you need a LEFT JOIN query like
SELECT h.`slug` from HighlightTable h
LEFT JOIN ArticleTable a ON h.`slug` = a.`slug`
LEFT JOIN UserTable u ON h.`slug` = u.`slug`;
Then do a separate JOIN and UNION the result set
SELECT h.`slug` from HighlightTable h
INNER JOIN ArticleTable a ON h.`slug` = a.`slug`
UNION
SELECT h.`slug` from HighlightTable h
INNER JOIN UserTable u ON h.`slug` = u.`slug`;
I'm having a hard time wrapping my head around how the column product_count works. It seems to be somehow referencing itself with aliases see and e, which are both pointing to catalog_category_entity. Specifically,
WHERE (see.entity_id = e.entity_id) OR (see.path LIKE CONCAT(e.path, '/%'))
Both see and e are aliases for table catalog_category_entity. What is this doing?
Here's the entire query:
SELECT `e`.*, `d_name`.`value` AS `name`, IF(s_name.value_id > 0, s_name.value, d_name.value) AS `name`, `d_is_active`.`value` AS `is_active`, IF(s_is_active.value_id > 0, s_is_active.value, d_is_active.value) AS `is_active`, `d_is_anchor`.`value` AS `is_anchor`, IF(s_is_anchor.value_id > 0, s_is_anchor.value, d_is_anchor.value) AS `is_anchor`,
(
SELECT COUNT(DISTINCT scp.product_id)
FROM `catalog_category_entity` AS `see`
LEFT JOIN `catalog_category_product` AS `scp`
ON see.entity_id=scp.category_id
WHERE (see.entity_id = e.entity_id) OR (see.path LIKE CONCAT(e.path, '/%'))
) AS `product_count`,
(
SELECT COUNT(cp.product_id)
FROM `catalog_category_product` AS `cp`
WHERE (cp.category_id = e.entity_id)
) AS `self_product_count`
FROM `catalog_category_entity` AS `e`
LEFT JOIN `catalog_category_entity_varchar` AS `d_name` ON d_name.entity_id=e.entity_id AND d_name.attribute_id=41 AND d_name.entity_type_id=e.entity_type_id AND d_name.store_id=0
LEFT JOIN `catalog_category_entity_varchar` AS `s_name` ON s_name.entity_id=e.entity_id AND s_name.attribute_id=41 AND s_name.entity_type_id=e.entity_type_id AND s_name.store_id=0
LEFT JOIN `catalog_category_entity_int` AS `d_is_active` ON d_is_active.entity_id=e.entity_id AND d_is_active.attribute_id=42 AND d_is_active.entity_type_id=e.entity_type_id AND d_is_active.store_id=0
LEFT JOIN `catalog_category_entity_int` AS `s_is_active` ON s_is_active.entity_id=e.entity_id AND s_is_active.attribute_id=42 AND s_is_active.entity_type_id=e.entity_type_id AND s_is_active.store_id=0
LEFT JOIN `catalog_category_entity_int` AS `d_is_anchor` ON d_is_anchor.entity_id=e.entity_id AND d_is_anchor.attribute_id=51 AND d_is_anchor.entity_type_id=e.entity_type_id AND d_is_anchor.store_id=0
LEFT JOIN `catalog_category_entity_int` AS `s_is_anchor` ON s_is_anchor.entity_id=e.entity_id AND s_is_anchor.attribute_id=51 AND s_is_anchor.entity_type_id=e.entity_type_id AND s_is_anchor.store_id=0
WHERE (`e`.`entity_type_id` = '3') AND (e.entity_id IN('24', '533')) ORDER BY LENGTH(e.path) ASC
This is an example of a correlated query, here the query owner is checking a condition from outside of the sub-query with an OR clause.
In the below sub-query there is a distinct count of production_id which should exist in both tables: catalog_category_entity and catalog_category_product (even here there is no requirement of left join and an inner join may work better as you get count from the right side table) with condition that either entitiy_id should exist in catalog_category_entity as main table OR sub-query path field should match with the main table left part of path field means the main table may contain an extra string in right side but the left part should be same.
SELECT COUNT(DISTINCT scp.product_id)
FROM `catalog_category_entity` AS `see`
LEFT JOIN `catalog_category_product` AS `scp`
ON see.entity_id=scp.category_id
WHERE (see.entity_id = e.entity_id)
OR (see.path LIKE CONCAT(e.path, '/%'))
You can simplify your query if the requirement is clear as you are joining table catalog_category_entity_int 4 times with left join, while you can use as below only a single time:
LEFT JOIN catalog_category_entity_int` AS `d_is_anchor`
ON d_is_anchor.entity_id=e.entity_id
AND d_is_anchor.attribute_id IN (42,51)
AND d_is_anchor.entity_type_id=e.entity_type_id
AND d_is_anchor.store_id=0
I have three tables that looks something like this:
Table joins
|ID|JOIN_NAME|
1 persons
2 companies
Table information
|ID|JOIN_ID|
1 1
2 2
Table information_extra_persons
|ID|INFORMATION_ID|NAME|
1 1 John
Table information_extra_companies
|ID|INFORMATION_ID|NAME|
1 2 IBM
How can i join together these tables in one SQL? I've tried something like:
SELECT * FROM `information`
INNER JOIN `information_extra_(SELECT `name` FROM `joins` WHERE `id` = `join_id`)`
ON `information_extra_(SELECT `name` FROM `joins` WHERE `id` = `join_id`)`.`information_id` = `information`.`id`
but I can't get it to work. Of course this isn't my actual table setup, but it's the same principle. Does anyone know how to get all the info in just one SQL?
That's actually four tables, not three. This isn't just a nitpick - it looks as though the substance of your question is "how can I use the name of the table as part of the join criteria?" (ie. how can the information_extra_ tables be treated as a single table?)
To which the answer is: you can't. (Outside of dynamic SQL.)
In this specific case, the following should return what I think you are looking for:
select j.join_name joined_entity,
case when j.join_name = 'persons' then p.name
else c.name
end joined_entity_name
from information i
inner join joins j on i.join_id = j.id
left join information_extra_persons p on i.id = p.information_id
left join information_extra_companies c on i.id = c.information_id
Alternatively, a less efficient (but more general) approach might be:
select j.join_name joined_entity,
v.name joined_entity_name
from information i
inner join joins j on i.join_id = j.id
inner join (select 'persons' entity, information_id, name from information_extra_persons
union all
select 'companies' entity, information_id, name from information_extra_companies) v
on i.id = v.information_id and j.join_name = v.entity