sql query from 4 tables - sql

I'm beginner and I need help!!!!!
I have a database:
article: id, name, description, id_pic, lang, date
category: id_cat, name_cat
pictures: id_pic, image
sub_cat: id_subcat, name_subcat, id_cat
I need to SELECT name, desc, image, name_subcat this on
SELECT
a.id, a.name, a.desc, sc.name_subcat, p.picture, a.id_subcat
FROM
article a, subcategory sc
LEFT JOIN
pictures p ON a.id_pic = p.id_pic
WHERE
a.id_subcat = sc.id_subcat
AND a.id_subcat IN (SELECT sc.id_subcat
FROM subcategory sc
WHERE id_cat = (SELECT id_cat
FROM category
WHERE name_cat = '???????'))

Try this:
SELECT a.id, a.name, a.desc,
sc.name_subcat, p.picture, a.id_subcat
FROM article a,
LEFT JOIN subcategory sc ON a.id_subcat = sc.id_subcat
LEFT JOIN categories c ON sc.id_cat = c.id_cat
LEFT JOIN pictures p ON a.id_pic = p.id_pic
WHERE c.name_cat = '??????'
Just join the table subcategory with other tables instead of where a.id_subcat = sc.id_subcat. This join will ensure that any a.id_subcat is in subcategory, so you can get rid of the subquery in the where clause too. You will also need to join the categories c table too.
You will need to choose the JOIN type whether left ot INNER, depending on what data to select from your table.

You seem to be missing some joins defines.
Four tables:
Article:
ID
Name
Description
ID_Pic
Lang
Date
Category:
id_cat
name_cat
Subcategory:
id_subcat
name_subcat
id_cat
Pictures:
id_pic
image,
We need to see how Category/Subcategory relate to articles. Do articles have a category they are linked to that you are missing afield from?
When you can get me these answers i can go through a join process for you.
EDIT: I see the missing field. Please ignore, good answer above me.
Regards,
Jason

Related

Count by partition

I have a bunch of rows(fruits) in a table, along with the basic details like fruit name, description color.
I want to know how many people viewed that product, how people liked it, etc...
This is what I tried but it is returning completely wrong numbers:
SELECT
vw.[Id],
vw.[Name],
vw.[Color],
-- This is returning 268 for id 1 but it supposed to be 134
(COUNT(v.PublicImageViewId) OVER (PARTITION BY v.[publicImageId] )) AS [ViewCount],
-- This is returning 268 for id 1 but it supposed to be 2, both these counts are same and wrong
(COUNT(u.PublicImageUpvoteId) OVER (PARTITION BY v.[publicImageId] )) AS [UpvoteCount]
FROM
[PublicImage] vw
LEFT JOIN
[PublicImageUpvote] u ON u.[PublicImageId] = vw.[PublicImageId]
LEFT JOIN
[PublicImageFavourite] f ON f.[PublicImageId] = vw.[PublicImageId]
LEFT JOIN
[PublicImageView] v ON v.PublicImageId = vw.[PublicImageId]
This might not be done like this or I'm doing blunder mistake.
All I wanted is for each product no of views, no of likes, no of favorites ...etc
Tables:
Public Image Table
PublicImageId: PK
name, color
PublicImageUpvote (same for PublicImageView, PublicImageFavourite)
PublicImageUpvoteId: PK
PublicImageId: FK
CreatedBy, Created Date
You must GROUP BY vw.[Id], vw.[Name], vw.[Color] and count the distinct values:
SELECT
vw.[Id],
vw.[Name],
vw.[Color],
COUNT(DISTINCT v.PublicImageViewId) AS [ViewCount],
COUNT(DISTINCT u.PublicImageUpvoteId) AS [UpvoteCount]
FROM [PublicImage] vw
LEFT JOIN [PublicImageUpvote] u ON u.[PublicImageId] = vw.[PublicImageId]
LEFT JOIN [PublicImageFavourite] f ON f.[PublicImageId] = vw.[PublicImageId]
LEFT JOIN [PublicImageView] v ON v.PublicImageId = vw.[PublicImageId]
GROUP BY vw.[Id], vw.[Name], vw.[Color]
May I suggest that you need another table for this
How many people viewed that product, how people liked it, etc...
Then use JOIN

How can I get data for one field from multiple tables?

I have a column ContentID in a table that identifies content that exists in other tables. For example, it could refer to a pageID, productID, etc. My plan is to use that to pull through other information I need, such as a page name or product name. This is what I have so far:
SELECT TL.ID, TL.TableName, TL.FileName, TL.ContentID, p.PageName AS Content
FROM TranslationLog TL
LEFT JOIN Pages P ON TL.ContentID = P.PageID
LEFT JOIN Categories C ON TL.ContentID = C.CategoryID
LEFT JOIN ProductDescriptions PD ON TL.ContentID = PD.SKU
The idea is for each row, I want to get the data for the specified content using the TableName and ContentID fields. Currently, I'm able to get PageName by selecting p.PageName AS Content. However, I'd like to do this for each of the tables; if the row corresponds to the pages table, then query that table - same for categories and product descriptions. I also need it to have the alias "Content", regardless of which field from another table we're using, such as PageName or ProductName.
Is it possible to do this?
EDIT:
The solution posted by rd_nielsen was almost perfect, but it turned out there was actually a bit of overlap with the ContentID. Here's what I ended up with to fix it:
SELECT TL.ID, TL.TableName, TL.FileName, TL.ContentID, coalesce(P.PageName, C.CategoryName, PD.ProductName)
FROM TranslationLog TL
LEFT JOIN Pages P ON TL.ContentID = P.PageID AND TL.TableName = 'Pages'
LEFT JOIN Categories C ON TL.ContentID = C.CategoryID AND TL.TableName = 'Categories'
LEFT JOIN ProductDescriptions PD ON TL.ContentID = PD.SKU AND TL.TableName = 'Products'
You should use cross-apply. For example:
select
T.*
from
table_stored_data u
cross apply dbo.created_function(u.contentid,u.tablename,u.search_column) T
You need to write a function for it.
If the values of TranslationLog.ContentID can appear in only one of the related tables, then you can coalesce the values from those tables:
SELECT
TL.ID,
TL.TableName,
TL.FileName,
TL.ContentID,
coalesce(p.PageName, C.CategoryName, PD.ProductName) AS Content
FROM
...
Try concat function:
select concat(p.PageName, C.CategoryName, PD.ProductName) AS Content from ...

What am I missing this? Do I need to use JOIN or UNION or a subquery?

I'm trying to get some practice making queries with SQL.
I'm working with a playground that uses SQLite.
There are two tables:books_north and books_south
Both have columns for: id, title, author, genre and first_published
The query I'm trying is to generate a report that lists the book titles from both locations and count the total number of books with the same title.
I can't work out how to even get started with the count.
So far I have
SELECT title
FROM books_north
INNER JOIN books_south
ON books_north.title = books_south.title;
But it just says that title is an ambiguous column.
How do I do this? Thank you
You need UNION ALL to get the count of each title
Select Title,Count(1) as [Count]
From
(
SELECT title FROM books_north bn
union all
select title from books_south bs
) A
Group by Title
Another approach using FULL OUTER JOIN (If your RDBMS supports)
SELECT COALESCE(bn.Title, bs.title) as title,
( bn.[count] + bs.[count] ) AS [Count]
FROM (SELECT title,
Count(1) AS [count]
FROM books_north
GROUP BY title) bn
FULL OUTER JOIN (SELECT title,
Count(1) AS [count]
FROM books_south
GROUP BY title) bs
ON bn.Title = bs.Title
Regarding your error message, Title column is present in the both the table so when you select the Title column you need to tell the compiler from which table you want to select Title column. It can be done by giving a alias name to the tables in Join
SELECT COUNT( DISTINCT a.title) AS TITLECount
FROM books_north a
INNER JOIN books_south b
ON a.title = b.title;
A simple inner join would be sufficient to get your count. Use a table alias in SELECT to remove the ambiguity of column title as it is present in both the tables.
In regard to the error that you mentioned:
The problem is SELECT title - it asks you to be specific about where title shall be read from, books_north or books_south.
So you need to tell either SELECT book_north.title or SELECT book_south.title, that's all there is regarding the ambiguity error.
The count is explained in the other answers. You need to learn group by if you want to display title and count (it is basically a group by title in your case.
SELECT books_north.title, count(books_north.title)
FROM books_north
INNER JOIN books_south
ON books_north.title = books_south.title
GROUP BY books_north.title;
This works:
SELECT title, COUNT(title) count FROM
(
SELECT title FROM books_north
UNION ALL
SELECT title FROM books_south
)
GROUP BY title;

Get correct result from mysql query

I have the following tables:
**products** which has these fields: id,product,price,added_date
**products_to_categories** which has these fields: id,product_id,category_id
**adverts_to_categories** -> id,advert_id,category_id
**adverts** which has these fields: id,advert_name,added_date,location
I can not execute sql that will return to me all products that are from category 14 and that are owned by advert located in London. So I have 4 tables and 2 conditions - to be from category 14 and the owner of the product to be from London. I tried many variants to execute sql but none of the results were correct.. Do I need to use Join and which Join - left, right, full? How the correct sql will look like? thank you in advance for your help and sorry for boring you :)
This is what I have tried so far:
SELECT p.id, product, price, category_id,
p.added_date, adverts.location, adverts.id
FROM products p,
products_to_categories ptc,
adverts,
adverts_to_categories ac
WHERE ptc.category_id = "14"
AND ptc.product_id=p.id
AND ac.advert_id=adverts.id
AND adverts.location= "London"
pretty basic logic
Select * from Products P
INNER JOIN Products_To_Categories PTC ON P.ID = PTC.Product_ID
INNER JOIN Adverts_to_Categories ATC ON ATC.Category_Id = PTC.Category_ID
INNER JOIN Adverts AD on AD.ID = ATC.Advert_ID
WHERE PTC.Category_ID = 14 and AD.Location = 'LONDON'
you would only need a LEFT or right join IF you wanted records from a table which didn't exist in other tables.
so for example, if you wanted all products even if a records even those without a category, then you would use a LEFT Join instead of inner.
The following statement should return all columns from the product table in category with id 14 and all adverts located in London:
select p.* from products p
inner join products_to_categories pc on p.id = pc.product_id
inner join adverts_to_categories ac on pc.category_id = ac.category_id
inner join adverts a on a.id = ac.advert_id
where pc.category_id = 14
and ac.location = 'London';
You should remember to add an index to the column location if you are doing these string-based queries very often.

SQL Join three tables

I'm learning advanced SQL queries little by little and I'm fairly stumped with a problem:
I have three tables: news, author, and images. Each field in the news table (newsID) is a news story, which then has an associated author in the author table (authorID) and can have any number of images associated in the images table. Each image has and associated (newsID). So each story has one author but can have several images.
I want to make a list of all news stories and use just one of the images as a thumbnail image. The problem is that any sql query I try to list the news items with gives me results equal to the number of images in the images table rather than the number of news items.
I don't know where to go from here. Any help would be greatly appreciated.
If the 3 tables in question are [news], [author] and [image] with appropriate columns, then
Derived Table approach
you can have a derived image table to get one image per news and then join it with the news and author table as shown.
This has been written and tested in SQL Server.
SELECT
N.[newsStoryTitle]
,A.authorName
,I.imageData1
FROM [news] N
LEFT OUTER JOIN author A ON A.newsID = N.newsID
LEFT OUTER JOIN
(
SELECT newsID, MAX(imageData) AS imageData1 FROM [image]
GROUP BY newsID
) AS I ON I.newsID = N.newsID
ORDER BY N.newsID
You could replace the LEFT OUTER JOINs with INNER JOINs if you do not need news without any images.
Correlated Subquery approach (as suggested by Marcelo Cantos)
If the imageData is stored as a text or image, then the MAX in the derived table wouldn't work. In that case, you can use a correlated subquery like this:
SELECT N.newsStoryTitle ,
A.authorName ,
I.imageData
FROM dbo.news N
INNER JOIN dbo.author A ON N.newsID = A.newsID
INNER JOIN dbo.image I ON N.newsID = I.newsID
WHERE imageID = ( SELECT MAX(imageID)
FROM dbo.image
WHERE newsID = N.newsID
)
ORDER BY n.newsID
One option is to add the following predicate:
FROM news JOIN images ...
...
WHERE imageID = (SELECT MAX(imageID)
FROM image
WHERE newsID = news.newsID)
Note that this excludes news items without an image. If you don't want this, you'll need a left join on images and an additional condition on the WHERE:
FROM news LEFT JOIN images ...
...
WHERE imageID IS NULL
OR imageID = (SELECT MAX(imageID)
FROM image
WHERE newsID = news.newsID)
You can to modify the order by on the subselect to get the 1 image per news row you are looking for...
select
....
from news n
left outer join images i on i.imageID = (
select top 1 i2.imageID
from images i2
where i2.newsID = n.newsID
order by --??
)
If you have 3 table in mysql and you want to join it together. for example I have 3 table
1 student
2 subject
3 score
now want to join student with subject and score. so we you this syntax :
select * from student inner join subject inner join score;