How can I Count in multiple table? - mysql

I have some problem to get the ID which use on another table row. I have three tables. One is category, articles, video. In articles and video there is a column which have category ID. This is the example:
Table Categories :
id | category_name
------------------
1 | News
2 | Sports
3 | Art
4 | Horror
Table Articles :
id | category_id | title
----------------------------------
1 | 1 | title content 1
2 | 1 | title content 2
3 | 3 | title content 3
4 | 3 | title content 4
5 | 2 | title content 5
Table Video :
id | category_id | video_title
------------------------------
1 | 1 | video title 1
2 | 2 | video title 2
3 | 3 | video title 3
I want to get each category ID already use what time in two other databases. Like this :
Category ID 1 is use 3 times
Category ID 2 is use 2 times
Category ID 3 is use 3 times
Category ID 4 is use 0 times
What query do I need to use so I can get all data like that ? Please anyone knows could help me. Thanks in advance.

First you need to UNION ALL articles table and video table be a subquery, then use Outer join and COUNT function.
SELECT Concat('Category ID ', c.id, ' is use ', Count(t.category_id ), ' times')
FROM categories c
LEFT JOIN (SELECT category_id
FROM articles
UNION ALL
SELECT category_id
FROM video) t
ON c.id = t.category_id
GROUP BY c.id
SQLFIDDLE:http://sqlfiddle.com/#!9/92cbd0e/12
[Results]:
| Concat('Category ID ', t.id, ' is use ', t.cnt, ' times') |
|------------------------------------------------------------|
| Category ID 1 is use 3 times |
| Category ID 2 is use 2 times |
| Category ID 3 is use 3 times |
| Category ID 4 is use 0 times |
NOTE
COUNT function does not count numbers if the column value encounters null
For example Here is a sample script.
CREATE TABLE T(
col int
);
INSERT INTO T VALUES (NULL);
INSERT INTO T VALUES (1);
SELECT COUNT(col) FROM t; -- RESULT = 1
SELECT COUNT(*) FROM t; --RESULT = 2
sample sqlfiddle:http://sqlfiddle.com/#!9/e2bba7/2

You can use, for example, this query:
Select category_id, count(1) - 1
From (
Select category_id From video
Union All Select category_id From articles
Union All Select id From Categories)
Group By category_id

Related

Search for multiple conditions on same column?

In SQL, how to select all rows that satisfy multiple AND conditions (not OR) of the same column?
Such as: "select all users who speak these 3 languages (language_id == 1 AND language_id == 2 AND language_id ==3)" where language_id is a column
id | user_id | language_id
--------------------------
1 | 1 | 1
2 | 2 | 1
3 | 2 | 2
4 | 3 | 1
5 | 4 | 1 << which users speak this language )
6 | 4 | 2 << AND speak this language ) => expected result: user_id == 4
7 | 4 | 3 << AND speak this language )
8 | 5 | 1
9 | 6 | 1
10 | 7 | 1
First select all users having the wanted languages, count the languages and then restrict the users to have the language count equal to the count of the wanted languages.
SELECT user_id
FROM (SELECT used_id,COUNT(*)
FROM [table_name]
WHERE language_id IN (1,2,3)
GROUP BY user_id
HAVING COUNT(*)=3
) i;
You have some ways to do that.
One simple way would be to create a view returning the user_id with the count for each language, for example:
CREATE VIEW myView
AS
SELECT DISTINCT T0.user_id
,(SELECT COUNT(*) FROM [myTable] WHERE user_id=T0.user_id AND language_id=1) AS L1
,(SELECT COUNT(*) FROM [myTable] WHERE user_id=T0.user_id AND language_id=2) AS L2
,(SELECT COUNT(*) FROM [myTable] WHERE user_id=T0.user_id AND language_id=3) AS L3
FROM [myTable] AS T0
GO
You should get a result like this:
Then, you only need to query this view, getting just the user_id where L1>0 AND L2>0 AND L3>0...
SELECT * FROM myView WHERE L1>0 AND L2>0 AND L3>0
Regards,

Mysql - Select distinct column with column id query is not working

i have few duplicate rows in my mysql table which belongs to different different categories , my table structure is like this .
sample_table
-----------------------
id | title | category
-----------------------
1 |item 1 | category 1
2 |item 1 | category 2
3 |item 1 | category 3
4 |item 2 | category 1
5 |item 2 | category 3
my problem is I want distinct title column from my table along with their id ,I tried select distinct title from sample_table,it returns 2 rows,
but if i try select distinct title , id from sample_table it returns all 5 rows.
Now my problem is I want distinct title with their id's from table i.e 2 rows with their id's.
use group by
select id,title from sample_table group by title
Use instead select with a group by statement like that :
select title, group_concat(id separator ' ') as ids
from sample_table
group by title;
it will return 2 rows like that :
title ids
item1 1 2 3
item2 4 5

MySQL Product/Category/Catalog Join

I have an existing populated MySQL table with three columns: product_id, category_id and catalog_id
Each catalog has multiple categories in it and each category has multiple products in it. Categories belonging to the same catalog should have exactly the same products in them, but unfortunately they don't in certain cases.
I need to identify the missing products in each category. Missing means that a product exists in at least one other category that belongs to the same catalog but doesn't exist in that particular category.
So the result I need to get out of this is a list of product_id/category_id pairs that are missing and need to be added.
How do I accomplish this in MySQL?
I tried creating a table populated by the distinct product_id and catalog_id pairs to get all the products for each catalog and then join that with the main table, but I am not sure what type of join to perform.
Any MySQL experts willing to help?
Update:
Based on a request, here is the create table SQL (this is a simplified version of the actual scenario):
create table product (
product_id bigint not null,
category_id bigint not null,
catalog_id bigint not null
);
Update 2:
Clarification: Every category that belongs to the same catalog must have the same exact products in it as all the other categories that belong to the same catalog. If a product is in one category and not in another category that belongs to the same catalog, then it is missing and needs to be identified as a product_id/category_id pair.
Update 3:
Per another request, here is sample data:
insert into product (product_id, category_id, catalog_id) values (1, 1, 1);
insert into product (product_id, category_id, catalog_id) values (2, 1, 1);
insert into product (product_id, category_id, catalog_id) values (3, 1, 1);
insert into product (product_id, category_id, catalog_id) values (1, 2, 1);
insert into product (product_id, category_id, catalog_id) values (3, 2, 1);
In this case the pair of product_id 2 and category_id 2 would be identified as part of the result. This is because categories 1 and 2 belong to the same catalog (1) and category 2 has a missing product, namely product_id 2.
You can do it using the following query:
SELECT s1.product_id, s1.category_id
FROM (
SELECT t1.product_id, t2.category_id, t1.catalog_id
FROM (
SELECT DISTINCT product_id, catalog_id
FROM product) AS t1
CROSS JOIN (
SELECT DISTINCT category_id, catalog_id
FROM product) AS t2
WHERE t1.catalog_id = t2.catalog_id ) AS s1
LEFT JOIN product AS s2
ON s1.catalog_id = s2.catalog_id AND
s1.category_id = s2.category_id AND
s1.product_id = s2.product_id
WHERE s2.product_id IS NULL
Demo here
Explanation:
This query:
SELECT DISTINCT product_id, catalog_id
FROM product
gives you a list of all distinct products per catalog:
product_id catalog_id
-----------------------
1 1
2 1
3 1
If you perform a CROSS JOIN of the above to all distinct categories per catalog:
SELECT t1.product_id, t2.category_id, t2.catalog_id
FROM (
SELECT DISTINCT product_id, catalog_id
FROM product) AS t1
CROSS JOIN (
SELECT DISTINCT category_id, catalog_id
FROM product) AS t2
WHERE t1.catalog_id = t2.catalog_id
you get:
product_id category_id catalog_id
----------------------------------
1 1 1
1 2 1
2 1 1
2 2 1
3 1 1
3 2 1
The above is a comprehensive set containing the full list of product_id per category_id per catalog_id.
All you have to do now is to find the missing product_id, category_id pairs from your table. You can do that with a use of a LEFT JOIN as in the initial query.
You can also do by this in optimize way-
Hitesh> select * from product; +------------+-------------+------------+
| product_id | category_id | catalog_id |
+------------+-------------+------------+
| 1 | 1 | 1 |
| 2 | 1 | 1 |
| 3 | 1 | 1 |
| 1 | 2 | 1 |
| 3 | 2 | 1 |
| 4 | 2 | 1 |
| 5 | 2 | 1 |
| 1 | 2 | 2 |
| 2 | 1 | 2 |
+------------+-------------+------------+
9 rows in set (0.00 sec)
Hitesh>
SELECT product_id, category_id, catalog_id
FROM
(SELECT DISTINCT p1.product_id, p2.category_id, p1.catalog_id
FROM product p1 JOIN product p2 ON p1.catalog_id=p2.catalog_id) tmp
WHERE NOT EXISTS (SELECT 1 FROM product
WHERE category_id = tmp.category_id AND
product_id=tmp.product_id AND
catalog_id=tmp.catalog_id);
+------------+-------------+------------+
| product_id | category_id | catalog_id |
+------------+-------------+------------+
| 4 | 1 | 1 |
| 5 | 1 | 1 |
| 2 | 2 | 1 |
| 2 | 2 | 2 |
| 1 | 1 | 2 |
+------------+-------------+------------+
5 rows in set (0.00 sec)

How to get 2 videos (that belongs to a program and program belogns to a category) for every category?

There 3 tables category, program, video. Every video belongs to a program, and any program belongs to a category.
Category table
id | title
1 | cartoons
2 | documental
Program table
id | programcode | title | category_id
1 | WUCU | Program Name | 1
2 | ELKI | Program Name | 2
Video table
id | videocode | title | program_id
1 | ELKI00001 | Name | 2
2 | ELKI00002 | Name | 2
3 | ELKI00003 | Name | 2
4 | WUCU00001 | Name | 1
5 | WUCU00002 | Name | 1
6 | WUCU00003 | Name | 1
I need to get last 2 videos for every category
The problem: MySQL doesn't support getting the top most N values in a group. So we have to do it ourselves. This means we need a way to group the sets together (Category.Title and a way to know which videos to return belonging to each category. We'd like to use LIMIT here to limit the results by 2 but we can't limit by 2 for each category. We'd also like to use MAX to get the highest video ID for each category but that doesn't get us the 2nd one. So we have to build those in ourselves.
This is built using logic found:
http://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/
but altered to fit your data set
This is working but I don't know why I'm having to do multiple subselects for #RNUM and #VCAT. Not sure why they have to be separated at this point. fiddle
set #Rnum :=0, #VCat :='';
SELECT * FROM (
Select SequencedSet.*, #Rnum := if(mvcat = CTitle, #Rnum + 1, 1) RowNumber from (
SELECT CTitle, VCode, VTitle, VID, #vcat mvcat,
#VCat := CTitle as VCAT
FROM (
SELECT C.Title CTitle, V.Code VCode, V.Title VTitle, V.ID VID
FROM Video V
INNER JOIN Program P
on P.ID = V.Program_Id
INNER JOIN Category C
on C.ID = P.Category_ID
ORDER BY C.Title, V.ID DESC) orderedset) sequencedSet) X
where X.ROWNUMBER<=2

my sql order by with values

I have a list of products which have an ID column as primary key, and category id which is a foreign key.. I want to overthem by a certain way.
ID | Name | CategoryID
----------------------------
1 | one | 1
2 | two | 2
3 | three | 1
4 | four | 3
5 | five | 5
6 | six | 4
7 | seven | 2
8 | eight | 1
if the above is my table. I want to get them in an SQL like the folowing
if want order these products in a certain way where all the products of category 5 needs to be
appearing first I am running a query like this.
SELECT * FROM Product ORDER BY CategoryID IN (5), ID
this does the job well.
but now i am in need to show the category id 5 first and then category id 2 first and the rest
if I try
SELECT * FROM Product ORDER BY CategoryID IN (5), CategoryID IN (2), ID ASC
that doesnt work.
any suggestions
You can use MySQL's FIELD() function:
SELECT * FROM Product ORDER BY FIELD(CategoryID, 2, 5) DESC
See it on sqlfiddle.
Try this way:
SELECT * FROM Product
ORDER BY
case CategoryID
when 5 then 0
when 2 then 1
else 2
end
, ID