How to extract an original table from a join in sql - mysql

with this database I did the next query :
WITH comp_courses AS
(SELECT * FROM course WHERE title LIKE "Comp%")
SELECT * FROM (instructor INNER JOIN (comp_courses INNER JOIN teaches USING(course_id)) USING(ID));
now that returns a join of a bunch of tables. But what I want is only the colmuns from that query that appear in instructor. Any ideas on how to do it?

All you would have to do is select all the columns from that table using the * operator like so:
instructor.*
This should get you the result your looking for:
SELECT
instructor.*
FROM
instructor AS `i`
JOIN teaches AS `t` ON `t`.id = `c`.id
JOIN course AS `c` ON `c`.course_id = `t`.course_id
WHERE
`c`.title LIKE 'Comp%';
Hope this helps,

Related

inner join and count records recursively

I have two tables named Topics and DocumentTopics
Topics table has the following structure
di_name | parentTopic
the records in Topics can be either a main or a child topic of a main topic. If a record is a main topic then the value of parentTopic will be null.
DocumentsTopics has the following structure
doc_name | topic_di_name
documentsTopics holds the records of all my documents by name and their topics. I can join both tables using topics->di_name and documentTopics->topic_di_name
SELECT t1.topic_di_name, count(t1.topic_di_name) as count
FROM DocumentsTopics t1
INNER JOIN Topics t2
ON t1.topic_di_name = t2.di_name
GROUP BY t1.topic_di_name;
but what I actually want to is group the topics by main topics only and get a sum count of all the records under the main topic and all its children's topics. These may drill down to more than one level.
here is a schema with sample data
There are 2 main topics but only one has siblings. The total count I am looking for is for the main topics only but they should include the counts of all the sibling topics within.
I am guessing the only way to do that is to run a recursive function but I am unsure about how to do that with a single SQL query. Is it even possible?
Any help would be greatly appreciated
Here's another way to do it using a UNION in a sub query in case this makes more sense to anyone:
SELECT `der`.`parentTopic`,
SUM(IF(`dt`.`topic_di_name` = `der`.`subTopic`,1,0)) AS `counter`
FROM (
SELECT `parentTopic`,
`di_name` AS `subTopic`
FROM `topics`
WHERE `parentTopic` IS NOT NULL
UNION
SELECT `di_name` AS `parentTopic`,
`di_name` AS `subTopic`
FROM `topics`
WHERE `parentTopic` IS NULL) AS `der`
JOIN `documentsTopics` AS `dt` ON `dt`.`topic_di_name` = `der`.`subTopic`
GROUP BY `der`.`parentTopic`
;
Here's this answer in sql fiddle.
Hope this helps!
Why can't you use:
SELECT t3.parent_key, count(t3.parent_key)
FROM DocumentsTopics t1
INNER JOIN Topics t2
ON t1.topic_di_name = t2.di_name
LEFT JOIN (select *, coalesce(parentTopic, di_name) parent_key from Topics) t3
ON t2.di_name = t3.di_name
GROUP BY t3.parent_key
Something like this should work for two levels.
https://www.db-fiddle.com/f/vcjUtUfxsn4yaKnQhmQJ6d/5
SELECT IFNULL(t.parentTopic,t.di_name) AS main_topics,COUNT(*) AS counter
FROM DocumentsTopics d
INNER JOIN Topics t ON d.topic_di_name=t.di_name
GROUP BY 1
I think this will work in mySql 8.0 and give you nested results more than one level deep, but I don't have access to test
with recursive cte as (
SELECT `parentTopic`,
`di_name`
FROM `topics`
WHERE `parentTopic` IS NOT NULL
union all
select
`parentTopic`,
`di_name`
from `topics` t2
inner join cte on t2.`parentTopic` = cte.`di_name`
)
select * from cte

Merge records or more into one in SQL

So I have this query:
SELECT *
FROM `Nieuws`
INNER JOIN `Nieuws_tags` ON `Nieuws_tags`.`ID-Nieuws` = `Nieuws`.`ID`
INNER JOIN `Tags` ON `Tags`.`ID` = `Nieuws_tags`.`ID-tags`
WHERE Nieuws.ID = 1
Right now my output is:
What I need:
So I need one record where the "Beschrijving" (tag) stack up and not give me 2 records.
Someone told me about GROUP_CONCAT but I don't really know how to insert that if necessary.
It is not 100% clear what is your DB schema, but just to show you the usage of GROUP_CONCAT function:
SELECT Nieuws.*,
GROUP_CONCAT(Tags.Beschrijving)
FROM `Nieuws`
INNER JOIN `Nieuws_tags`
ON `Nieuws_tags`.`ID-Nieuws` = `Nieuws`.`ID`
INNER JOIN `Tags`
ON `Tags`.`ID` = `Nieuws_tags`.`ID-tags`
WHERE Nieuws.ID = 1
GROUP BY Nieuws.ID

why don't i get return value in Mysql?

Why don't I get the result of this query in MySQL?
SELECT * FROM feature_product
INNER JOIN `product` on product.`product_id`=product_ref_id
WHERE ( feature_ref_id=11 or feature_ref_id=10 ) AND ( feature_ref_id=13 or feature_ref_id=13 )
Try this.
SELECT * FROM feature_product
INNER JOIN `product` on product.`product_id`=product_ref_id where
feature_ref_id NOT IN("10","11","13");
you will get the desired out put using this query.
SELECT * FROM feature_product fp
INNER JOIN product p on p.product_id=fp.product_ref_id
WHERE feature_ref_id in (11,10,13)
Please try above and it will be great if you share both table column name.

How make a subquery in a select all (*) for a view SQL?

I want to make a view with multiple tables, but what I need is select * from a table and select just a few from the rest of the tables. This is what I have until now:
CREATE VIEW `database`.`pages_view` AS
SELECT
`p`.`p_name` AS `p_name`,
`p`.`slug` AS `slug`,
`i`.`image` AS `image`,
`t`.`title` AS `title`,
`t`.`text` AS `text`,
`s`.`sec_name` AS `sec_name`
FROM
(((`database`.`pages` `p`
LEFT JOIN `database`.`page_image` `i` ON ((`p`.`id` = `i`.`pages_id`)))
LEFT JOIN `database`.`page_text` `t` ON ((`p`.`id` = `t`.`pages_id`)))
LEFT JOIN `database`.`sections` `s` ON ((`p`.`id` = `t`.`pages_id`)))
WHERE
(`p`.`visible` = 1)
What I want is select * from sections instead of call one by one.
Just use s.*:
CREATE VIEW database.pages_view AS
SELECT p.p_name, p.slug, i.image, t.title, t.text,
s.*
FROM database.pages p LEFT JOIN
database.page_image i
ON p.id = i.ages_id LEFT JOIN
database.page_text t
ON p.id = t.pages_id LEFT JOIN
database.sections s
ON p.id = t.pages_id
WHERE p.visible = 1;
Notes:
You do not need escape characters (unless you have poorly named table or columns).
This is especially true for table aliases.
You don't need to rename columns to the same name p.p_name as p_name is redundant -- not worth the extra typing.
Also, be careful when using * in a view. It is the answer to your question, but the names, types, and order of the columns depends on the underlying table.

INNER JOIN on selection

I have a problem with the inner join. I need to filter the table before it will combine tables using inner join. The following code is of course wrong but I need something like this. Please help.
SELECT * FROM hotel LEFT OUTER JOIN (**hotel_table where hotel_table.id_offer=$id**) ON (hotel.id = hotel_table.id_hotel)
Edit:
Thanks for the fast answer. But I get an error: "Every derived table must have its own alias" My code:
SELECT *
FROM
czajka_zakwaterowania
LEFT OUTER JOIN
(
SELECT *
FROM czajka_hotel_l
WHERE czajka_hotel_l.id_hotel=$id
)
ON (czajka_zakwaterowania.id = czajka_hotel_l.id_hotel)
How do I solve this?
This code displays the error: "Every derived table must have its own alias" I cant eliminate it.
SELECT *
FROM
hotel
LEFT OUTER JOIN
hotel_table ON hotel.id = hotel_table.id_hotel AND hotel_table.id_offer=$id
or
SELECT *
FROM
hotel
LEFT OUTER JOIN
(
SELECT *
FROM hotel_table
WHERE hotel_table.id_offer=$id
) ht ON hotel.id = ht.id_hotel