MySQL count number occurrences - mysql

I have this 2 tables:
Category:
cat_id|cat_type
1 | a
2 | b
3 | c
4 | d
and have
Meta:
met_id|met_name|user_id|met_type
10 | bla | 2 | 1
11 | blabla | 4 | 2
12 | foo | 1 | 3
13 | blafoo | 3 | 4
14 | foofoo | 5 | 4
How can I return something like this ?
cat_type|occurences
a | 1
b | 1
c | 1
d | 2
met_type is a foreign key from Category.

SELECT c.cat_type
, COUNT(m.met_type) AS occurrences
FROM categoty c LEFT JOIN meta m ON c.cat_id = m.met_type
GROUP BY c.cat_type

SELECT cate.cat_type as 'cat_id', count(meta.met_type) as 'occurences'
FROM Category cate
LEFT JOIN Meta meta on(cate.cat_id = meta.met_type)
GROUP BY meta.met_type

Related

MYSQL Select two tables with multiple which is not there

I try to use LEFT JOIN but I dont get the result I want.
I have 2 tables
Table 1:
Persons
UID | Names | GID
1 | Mike | 1
2 | Tom | 1
3 | Brenda | 1
4 | Sophie | 2
Table 2:
DailyLog
ID | UID | GID | DATE
1 | 1 | 1 | 2017-10-13
2 | 2 | 1 | 2017-10-13
3 | 3 | 1 | 2017-10-13
4 | 1 | 1 | 2017-10-13
5 | 2 | 1 | 2017-10-14
6 | 1 | 1 | 2017-10-14
7 | 1 | 1 | 2017-10-15
I want search a name who is not have a stamp date of today (2017-10-15) in GID 1,
a result like this:
UID | Name
2 | Tom
3 | Brenda
I use SQL Left Join, but the result not what I expected.
SELECT DISTINCT a.uid
, a.Name
, b.date
FROM Persons AS a
LEFT
JOIN dailylog AS b
ON a.uid = b.uid
AND a.gid = b.gid
WHERE (b.date IS NULL OR b.date !='2017-10-15' )
AND a.gid='1'
Thank you
you could use a not In clause
SELECT a.uid
, a.Name
, b.date
FROM Persons
where uid not in (
select uid from DailyLog
where GID = 1
and DATE = '2017-10-15'
)

Get multiple values in one column from SQL query

I have 3 tables.
A table:
id_a | description
-------------------
1 | X
2 | Y
3 | Z
4 | H
B table:
id_b | description
-------------------
1 | J
2 | K
3 | W
C table:
id_c | idex_a | idex_b | quantity
----------------------------------
1 | 1 | 1 | 10
2 | 1 | 2 | 32
3 | 2 | 3 | 41
4 | 1 | 3 | 10
5 | 3 | 2 | 24
6 | 3 | 3 | 26
How can I obtain this result?
A.id_a | A.description | All B.description, B.quantity IN C WHITH A.id_a = C.idex_a
1 | X | J[10], K[32], W[10]
2 | Y | W[41]
3 | Z | K[24], W[26]
4 | H |
You can try the following:
select a.id_a
, a.description
, coalesce( group_concat(distinct concat(b.description, '[', c.quantity, ']') order by b.id_b separator ', ')
, '')
from a
left join c on a.id_a = c.idex_a
left join b on b.id_b = c.idex_b
group by a.id_a
, a.description
SQLFiddle

MySQL how to get number of values from a user?

I have this 3 tables:
Users:
user_id|user_nick
1 | a
2 | b
Category:
cat_id|cat_type
1 | a
2 | b
3 | c
4 | d
Meta:
met_id|met_name|met_user|met_type
10 | bla | 1 | 1
11 | blabla | 2 | 2
12 | foo | 1 | 3
13 | blafoo | 2 | 4
14 | foofoo | 1 | 4
15 | foobla | 1 | 4
How can I return something like this ?
user_id|met_type|total
1 | 1 | 1
1 | 2 | 0
1 | 3 | 1
1 | 4 | 2
For just one user and not for all of them.
met_type is a foreign key from Category.
I've tried like this but no success :/
SELECT met_user, met_type, COUNT(*) FROM Meta GROUP BY met_user WHERE met_user = '1'
Query:
SELECT met_user, met_type, count(*)
FROM Meta
WHERE met_user='1'
GROUP BY met_type;
To get empty groups, you can use generateSeries() here:
SELECT m.met_user, g.meta_type, count(m)
FROM generate_series(1, 4) AS g(meta_type)
LEFT OUTER JOIN Meta AS m
ON m.met_user='1'
AND m.met_type=g.meta_type
GROUP BY g.meta_type, m.met_user
ORDER BY g.meta_type;
Check it out! I made an sql fiddle.

Count values over m/n connected tables in SQL

I have four tables and like to know how many locations and downloads a certain name has.
names and locations are connected via the names_locations table
Here are my tables:
Table "names"
ID | name
=========
1 | foo
2 | bar
3 | zoo
4 | luu
Table "locations"
ID | location
=============
1 | Hamburg
2 | New York
3 | Singapore
4 | Tokio
Table "names_locations"
ID | location_id | name_id
==========================
1 | 1 | 1
2 | 1 | 2
3 | 2 | 2
4 | 3 | 3
5 | 1 | 2
Table "downloads"
ID | name_id | timestamp
=========================
1 | 1 | 1394041682
2 | 4 | 1394041356
3 | 1 | 1394041573
4 | 3 | 1394041981
5 | 1 | 1394041683
Result should be:
ID | name | locations | downloads
=================================
1 | foo | 1 | 3
2 | bar | 3 | 0
3 | zoo | 1 | 1
4 | luu | 0 | 1
Here's my attempt (without the downloads column):
SELECT names.*,
Count(names_locations.location_id) AS location
FROM names
LEFT JOIN names_locations
ON names.ID = names_locations.name_id
GROUP BY names.ID
I think this would work.
SELECT n.id,
n.name,
COUNT(DISTINCT l.id) AS locations,
COUNT(DISTINCT d.id) AS downloads
FROM names n LEFT JOIN names_location nl
ON n.id = nl.name_id
LEFT JOIN downloads dl
ON n.id = dl.name_id
LEFT JOIN locations l
ON l.id = nl.location_id
GROUP BY n.id, n.name
All of those seem to work. here's another one.
SELECT
a.ID,
a.name,
COUNT(c.location) AS locations,
COUNT(d.timestamp) AS downloads
FROM names AS a
LEFT JOIN names_locations AS b on a.ID=b.name_id
LEFT JOIN locations AS c ON b.location_id=c.ID
LEFT JOIN downloads AS d ON a.ID=d.name_id
GROUP BY a.name
SELECT
t.id,t.n AS name,
count(location_id) AS locations,
t.downloads
FROM names_location
RIGHT JOIN
(SELECT
names.id AS id,
names.name AS n,
count(timestamp) AS downloads
FROM names
LEFT JOIN downloads ON names.id = downloads.name_id
GROUP BY id) AS t
ON t.id = names_location.name_id
GROUP BY t.id
Output:
+------+------+-----------+-----------+
| id | name | locations | downloads |
+------+------+-----------+-----------+
| 1 | foo | 1 | 3 |
| 2 | bar | 3 | 0 |
| 3 | zoo | 1 | 1 |
| 4 | luu | 0 | 1 |
+------+------+-----------+-----------+
4 rows in set (0.00 sec)

double JOIN and GROUP on hasMany associations

I have 3 models (tables):
Presentation hasMany PresentationView hasMany SlideView
Fields:
Presentation: id, title
PresentationView: id, presentation_id
SlideView: id, presentation_view_id, duration
I need a query to get statistics for each presentation. Statistics are:
number of PresentationView per each Presentation
total duration of all SlideView.duration from slide views that belong to Presentation (through PresentationView)
So basically it seems like double JOIN and double GROUP but the joins doesn't work for me - I tried every combination of LEFT/INNER/RIGHT double joins and I can't make it work. The best I had it was that Presentation had grouped PresentationView but duration was SUMed just from SlideViews that belonged to just one PresentationViews not all for Presentation...
I would like to avoid nested SELECTs if possible. just JOIN/GROUP
The first thing is a simple JOIN and COUNT:
SELECT p.id, COUNT(*)
FROM Presentation p
JOIN PresentationView v ON p.id = v.presentation_id
GROUP BY p.id
The second one has to use a SUM (and JOIN):
SELECT p.id, SUM(s.duration)
FROM Presentation p
JOIN PresentationView v ON p.id = v.presentation_id
JOIN SlideView s ON v.id = s.presentation_view_id
GROUP BY p.id
If you want both in a single query:
SELECT p.id, SUM(s.duration), COUNT(DISTINCT v.id)
FROM Presentation p
JOIN PresentationView v ON p.id = v.presentation_id
JOIN SlideView s ON v.id = s.presentation_view_id
GROUP BY p.id
Reason for DISTINCT:
Tables:
Presentation: PresentationView: SlideView:
p.id | title v.id | presentation_id s.id | presentation_view_id | duration
1 | abc 1 | 1 1 | 1 | 100
2 | xyz 2 | 1 2 | 1 | 150
3 | 1 3 | 2 | 200
4 | 1 4 | 2 | 250
5 | 1 5 | 3 | 300
6 | 2 6 | 3 | 400
7 | 2 7 | 4 | 500
8 | 5 | 600
9 | 6 | 100
10 | 6 | 200
11 | 7 | 350
Example result set BEFORE the group:
p.id | v.id | s.id | s.duration
-------------------------------
1 | 1 | 1 | 100
1 | 1 | 2 | 150
1 | 2 | 3 | 200
1 | 2 | 4 | 250
1 | 3 | 5 | 300
1 | 3 | 6 | 400
1 | 4 | 7 | 500
1 | 5 | 8 | 600
2 | 6 | 9 | 100
2 | 6 | 10 | 200
2 | 7 | 11 | 350
AFTER the group without distinct:
p.id | SUM | COUNT
------------------
1 | 8 | 2500
2 | 3 | 650
With distinct:
p.id | SUM | COUNT
------------------
1 | 5 | 2500
2 | 2 | 650
In mean time I found answer:
SELECT presentations.title, SUM(slide_views.duration), COUNT(DISTINCT presentation_views.id)
FROM presentations
LEFT JOIN presentation_views ON presentations.id = presentation_views.presentation_id
LEFT JOIN slide_views ON presentation_views.id = slide_views.presentation_view_id
GROUP BY presentations.id