Grouping MySQL results from query - mysql

I am trying to create a basic notification system. The function below works well, however I'd like to be able to group notifications for the same notification item into the same array item. So, any query result that has the same [item] and [item_id] would be grouped together and just update the count for that item group. So I guess adding a new array item count for that group? I have no idea how to approach this. Any help would be much appreciated.
Query Function:
function get_notifications($connect, $user_id) {
$query = "SELECT * FROM notifications WHERE for_id = {$user_id} AND seen = 0 ";
$result = mysqli_query($connect, $query) or die(mysql_error($connect));
while($row = mysqli_fetch_assoc($result)){
$notifs[] = $row;
}
return $notifs;
}
$notifs = get_notifications($connect, $_SESSION['user_id']);
Current Result:
Array
(
[0] => Array
(
[note_id] => 3
[for_id] => 20
[from_id] => 20
[item] => like_pp
[item_id] => 104
[seen] => 0
[date] => 2022-01-19 12:55:20
)
[1] => Array
(
[note_id] => 4
[for_id] => 20
[from_id] => 20
[item] => like_comment
[item_id] => 332
[seen] => 0
[date] => 0000-00-00 00:00:00
)
[2] => Array
(
[note_id] => 5
[for_id] => 20
[from_id] => 23
[item] => like_pp
[item_id] => 104
[seen] => 0
[date] => 0000-00-00 00:00:00
)
[3] => Array
(
[note_id] => 6
[for_id] => 20
[from_id] => 20
[item] => pp_like
[item_id] => 102
[seen] => 0
[date] => 2022-01-19 15:03:23
)
)
Desired Result: ([item] => like_pp and [item_id] => 104 were the same so combined and updated notification_count)
Array
(
[0] => Array
(
[note_id] => 3
[for_id] => 20
[from_id] => 20
[item] => like_pp
[item_id] => 104
[seen] => 0
[notification_count] => 2
[date] => 2022-01-19 12:55:20
)
[1] => Array
(
[note_id] => 4
[for_id] => 20
[from_id] => 20
[item] => like_comment
[item_id] => 332
[seen] => 0
[notification_count] => 1
[date] => 0000-00-00 00:00:00
)
[2] => Array
(
[note_id] => 6
[for_id] => 20
[from_id] => 20
[item] => pp_like
[item_id] => 102
[seen] => 0
[notification_count] => 1
[date] => 2022-01-19 15:03:23
)
)

I think what you need is a the query that groups by user_id (for who) and item_id (for what type of notif) and delivers the count of this group. Something like:
$query = "SELECT count(*) as notification_count, for_id, item_id FROM notifications WHERE for_id = {$user_id} AND seen = 0 group by for_id, item_id ";
Optionally, if you need in the output the name of the item, for displaying or other purposes, it can be also added:
$query = "SELECT count(*) as notification_count, for_id, item_id, item FROM notifications WHERE for_id = {$user_id} AND seen = 0 group by for_id, item_id, item ";

Use GROUP BY and aggregation functions.
SELECT MIN(note_id) AS note_id, MIN(for_id) AS for_id, MIN(from_id) AS from_id,
item, item_id, MIN(seen) AS seen, COUNT(*) AS notification_count, MIN(date) as date
FROM notifications
WHERE for_id = {$user_id} AND seen = 0
GROUP BY item, item_id

Related

How to return array while using GROUP BY

Right now, I have this query:
SELECT COUNT(*) AS Count, SUM(Ask) AS Ask, SUM(Cost) AS Cost, Provider, Factura FROM store_items
WHERE (
Provider NOT IN(SELECT Provider FROM store_provider_invoices)
AND Factura NOT IN(SELECT Factura FROM store_provider_invoices)
)
OR Factura NOT IN(SELECT Factura FROM store_provider_invoices)
GROUP BY Provider, Factura
This is working great, and returns the following array:
Array (
[0] => Array (
[Count] => 1
[ID] => 13
[Ask] => 20.00
[Cost] => 10.00
[Provider] => 5
[Factura] => 8
)
[1] => Array (
[Count] => 1
[ID] => 18
[Ask] => 125.01
[Cost] => 110.01
[Provider] => 5
[Factura] => 34
)
[3] => Array (
[Count] => 3
[ID] => 14
[Ask] => 210.00
[Cost] => 150.00
[Provider] => 6
[Factura] => 5
)
)
What I would like to do is to also return all the ID's that match the query from the store_items table, like:
Array (
[0] => Array (
[ID] => Array (
[0] => 101
)
[Count] => 1
[Ask] => 20.00
[Cost] => 10.00
[Provider] => 5
[Factura] => 8
)
[1] => Array (
[ID] => Array (
[0] => 102
)
[Count] => 1
[Ask] => 125.01
[Cost] => 110.01
[Provider] => 5
[Factura] => 34
)
[3] => Array (
[ID] => Array (
[0] => 103
[1] => 104
[2] => 105
)
[Count] => 3
[Ask] => 210.00
[Cost] => 150.00
[Provider] => 6
[Factura] => 5
)
)
So, for instance, in the last array element above, instead of just returning a Count of 3, also return the ID's of each row that it counted.
You can't really get nested results, but you could use
GROUP_CONCAT(DISTINCT store_items.ID ORDER BY ID) AS siIDs
to get a comma-separated list of id values.
You can also modify the separator
http://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html#function_group-concat

Optimizing an union SQL query

I've got a big query that all contain same types I need for a feed that I list in my app. Now the problem is that this query isn't very fast. I'm thinking that if I limit each individual union it might speed it up a bit but I'm not sure.
So basically my question is how could I optimize this query to execute faster?
SELECT DISTINCT
alert_id,
uniquekey,
type,
user_id,
date_added
FROM
(
( SELECT
r.alert_id,
r.alert_id AS uniquekey,
'reply' AS `type`,
r.user_id,
r.date_added
FROM
`reply` r
LEFT JOIN `alerts` a
ON r.alert_id = a.alert_content_id
WHERE
r.user_id = :id
AND a.hide = '0'
ORDER BY
date_added DESC )
UNION
( SELECT
r.alert_id,
r.alert_id AS uniquekey,
'replyfromfollowing' AS `type`,
r.user_id,
r.date_added
FROM
`reply` r
LEFT JOIN `alerts` a
ON r.alert_id = a.alert_content_id
WHERE
r.user_id IN( '$followingstring' )
AND a.hide = '0'
ORDER BY date_added DESC )
UNION
( SELECT
i.alert_id,
i.alert_id AS uniquekey,
'liked' AS `type`,
i.user_id,
i.date_added
FROM
`interactions` i
LEFT JOIN `alerts` a
ON i.alert_id = a.alert_content_id
WHERE
i.user_id = :id
AND a.hide = '0'
GROUP BY
alert_id
ORDER BY
date_added DESC )
UNION
( SELECT
i.alert_id,
i.alert_id AS uniquekey,
'likedfromfollowing' AS `type`,
i.user_id,
i.date_added
FROM
`interactions` i
LEFT JOIN `alerts` a
ON i.alert_id = a.alert_content_id
WHERE
i.user_id IN ( '$followingstring' )
AND a.hide = '0'
GROUP BY
alert_id
ORDER BY
date_added DESC )
UNION
( SELECT
alerts as alert_id,
alert_content_id AS uniquekey,
'following' AS `type`,
user_id,
date_added
FROM
alerts a
LEFT JOIN `alerts_content` ac
ON ac.id = a.alert_content_id
WHERE
a.user_id IN ( '$followingstring' )
AND ac.anoniem = '0'
AND a.hide = '0'
GROUP BY
alert_id
ORDER BY
date_added DESC )
) joined
GROUP BY
uniquekey
ORDER BY
date_added DESC
LIMIT
".(int)$start.",20"
table structures
Reply table Structure:
id
user_id
alert_id
description
reply_on_alert
reply_on_reply
date_added
Interaction table Structure:
id
alert_id
action_id
reply_id
user_id
date_added
Alerts table structure(Yes i know BIG mistake naming `id` : `alerts`):
alerts
title
alert_content_id
user_id
cat
lat
lon
state
hide
date_added
alerts_content table structure:
id
alert_id
description
img
results of query:
Array
(
[0] => Array
(
[alert_id] => 173404
[uniquekey] => 173404
[type] => reply
[user_id] => 2
[date_added] => 2015-06-01 16:34:16
)
[1] => Array
(
[alert_id] => 172174
[uniquekey] => 172174
[type] => replyfromfollowing
[user_id] => 1380
[date_added] => 2015-06-01 16:01:04
)
[2] => Array
(
[alert_id] => 171772
[uniquekey] => 171772
[type] => liked
[user_id] => 2
[date_added] => 2015-06-01 15:58:44
)
[3] => Array
(
[alert_id] => 149423
[uniquekey] => 149423
[type] => reply
[user_id] => 2
[date_added] => 2015-06-01 15:25:56
)
[4] => Array
(
[alert_id] => 164742
[uniquekey] => 164742
[type] => reply
[user_id] => 2
[date_added] => 2015-05-12 09:46:39
)
[5] => Array
(
[alert_id] => 163344
[uniquekey] => 163344
[type] => replyfromfollowing
[user_id] => 3
[date_added] => 2015-05-12 09:44:46
)
[6] => Array
(
[alert_id] => 164205
[uniquekey] => 164205
[type] => liked
[user_id] => 2
[date_added] => 2015-05-11 11:06:39
)
[7] => Array
(
[alert_id] => 160890
[uniquekey] => 160890
[type] => replyfromfollowing
[user_id] => 1380
[date_added] => 2015-05-08 14:29:34
)
[8] => Array
(
[alert_id] => 163002
[uniquekey] => 163002
[type] => replyfromfollowing
[user_id] => 1380
[date_added] => 2015-05-08 13:31:12
)
[9] => Array
(
[alert_id] => 159123
[uniquekey] => 159123
[type] => replyfromfollowing
[user_id] => 48
[date_added] => 2015-04-30 15:10:32
)
[10] => Array
(
[alert_id] => 150546
[uniquekey] => 150546
[type] => replyfromfollowing
[user_id] => 16
[date_added] => 2015-04-21 21:52:49
)
[11] => Array
(
[alert_id] => 149497
[uniquekey] => 149497
[type] => reply
[user_id] => 2
[date_added] => 2015-04-10 15:19:06
)
[12] => Array
(
[alert_id] => 141078
[uniquekey] => 141078
[type] => liked
[user_id] => 2
[date_added] => 2015-04-10 15:15:32
)
[13] => Array
(
[alert_id] => 125466
[uniquekey] => 125466
[type] => replyfromfollowing
[user_id] => 3
[date_added] => 2015-04-09 00:15:22
)
[14] => Array
(
[alert_id] => 134592
[uniquekey] => 134592
[type] => replyfromfollowing
[user_id] => 3
[date_added] => 2015-04-09 00:11:04
)
[15] => Array
(
[alert_id] => 124194
[uniquekey] => 124194
[type] => likedfromfollowing
[user_id] => 3
[date_added] => 2015-04-09 00:08:35
)
[16] => Array
(
[alert_id] => 128645
[uniquekey] => 128645
[type] => likedfromfollowing
[user_id] => 3
[date_added] => 2015-04-09 00:07:29
)
[17] => Array
(
[alert_id] => 144867
[uniquekey] => 144867
[type] => replyfromfollowing
[user_id] => 3
[date_added] => 2015-04-06 13:59:19
)
[18] => Array
(
[alert_id] => 133355
[uniquekey] => 133355
[type] => liked
[user_id] => 2
[date_added] => 2015-03-31 16:16:15
)
[19] => Array
(
[alert_id] => 141075
[uniquekey] => 141075
[type] => liked
[user_id] => 2
[date_added] => 2015-03-30 15:17:01
)
)
Some possibilities, in no particular order:
Optimization #1:
Use LIMIT in the subqueries, too. However, since you are using OFFSET, it may not be obvious how to do it.
Before the query, calculate $start+20 and put it into, say, $limit. Then use LIMIT $limit for the inner queries. No, don't use an OFFSET on them. This guarantees that you get enough rows from each query to satisfy the outer OFFSET $start LIMIT 20.
Optimization #2:
Restructure the tables so that you don't need to JOIN to another table (alerts) to find out whether to show the record. That is, having hide prevents a number of potential optimizations. Before advising further, we need to understand the need for LEFT. Are there rows in reply, etc, that are not in alerts? If not, get rid of the LEFT and look into searching alerts with theOFFSETandLIMIT`, then joining to the 4 other tables.
Optimization #3:
Restructure the data so that there is one core table, with alerts and the 4 other tables hanging off it. Be sure to have most (all?) of the fields needed for this query in this new table.
Optimization #4:
The current structure requires the full scan of each of the 4 tables before even thinking about OFFSET and LIMIT. This smells like "pagination"; is it? For optimizing "pagination", the goals are to avoid the table scan and OFFSET; instead remember where you "left off" so that the query can be
WHERE ... AND x < $left_off
ORDER by x DESC
LIMIT 20
This should make it possible to read only 20 rows, not the entire table(s). That would make the query much faster, especially for later pages. (A bigger OFFSET costs more time`)
I discuss pagination optimization in my blog.

mysql | calculate number of days in date range for selected Month

i have a query. query is all fine. just 1 logical thing remaining taking out the total number of days out of a date range for the selected month..
e-g i have to columns
1 ) project_assign_date //considering as start date
2 ) project_revoke_date // considering as end date
This is my total Query.
SELECT
E.employee_id AS EmployeeID,
ET.employment_id AS EmploymentID,
E.employee_code AS EmployeeCode,
EP.project_id AS ProjectID,
MLP.project_title AS ProjectTitle,
S.base_salary AS EmployeeBaseSalary,
IFNULL(EP.percentCharged, 0) AS PercentCharged,
A.allowance_amount AS EmployeeAllowance,
SUM(IFNULL(A.allowance_amount,0)) + IFNULL(S.base_salary, 0) AS MonthlySalary ,
project_assign_date AS ProjectAssignDate
FROM
(`employee_project` EP)
INNER JOIN `employment` ET
ON `ET`.`employment_id` = `EP`.`employment_id`
AND ET.trashed = 0
AND ET.current = 1
INNER JOIN `employee` E
ON `E`.`employee_id` = `ET`.`employee_id`
AND E.trashed = 0
AND E.enrolled = 1
INNER JOIN `ml_projects` MLP
ON `MLP`.`project_id` = `EP`.`project_id`
AND MLP.trashed = 0
INNER JOIN `salary` S
ON `S`.`employement_id` = `ET`.`employment_id`
AND S.trashed = 0
AND S.status = 2
LEFT JOIN `allowance` A
ON `A`.`employment_id` = `ET`.`employment_id`
AND A.trashed = 0
AND A.status = 2
LEFT JOIN `expense_claims` EC ON EC.employment_id = ET.employment_id AND EC.status = 2
WHERE `EP`.`trashed` = 0
AND EP.current = 1
AND CURRENT_DATE() >= MONTH(project_assign_date)
GROUP BY
E.employee_id,ET.employment_id,EP.project_id
im getting the result fine as showing below.
Array
(
[0] => stdClass Object
(
[EmployeeID] => 1
[EmploymentID] => 15
[EmployeeCode] => E-01
[EmployeeName] => Yasir Khan
[ProjectID] => 1
[ProjectTitle] => Human Resource Management
[ProjectAbbreviation] => HRM
[EmployeeBaseSalary] => 45000.00
[PercentCharged] => 60
[MonthlySalary] => 45000.00
)
[1] => stdClass Object
(
[EmployeeID] => 1
[EmploymentID] => 15
[EmployeeCode] => E-01
[EmployeeName] => Yasir Khan
[ProjectID] => 2
[ProjectTitle] => telenor
[ProjectAbbreviation] => ASD
[EmployeeBaseSalary] => 45000.00
[PercentCharged] => 40
[MonthlySalary] => 45000.00
)
[2] => stdClass Object
(
[EmployeeID] => 9
[EmploymentID] => 20
[EmployeeCode] => E-120
[EmployeeName] => Izhar Ali
[ProjectID] => 1
[ProjectTitle] => Human Resource Management
[ProjectAbbreviation] => HRM
[EmployeeBaseSalary] => 35000.00
[PercentCharged] => 50
[MonthlySalary] => 35000.00
)
[3] => stdClass Object
(
[EmployeeID] => 9
[EmploymentID] => 20
[EmployeeCode] => E-120
[EmployeeName] => Izhar Ali
[ProjectID] => 2
[ProjectTitle] => telenor
[ProjectAbbreviation] => ASD
[EmployeeBaseSalary] => 35000.00
[PercentCharged] => 50
[MonthlySalary] => 35000.00
)
[4] => stdClass Object
(
[EmployeeID] => 19
[EmploymentID] => 32
[EmployeeCode] => E-014
[EmployeeName] => Said Ullah
[ProjectID] => 1
[ProjectTitle] => Human Resource Management
[ProjectAbbreviation] => HRM
[EmployeeBaseSalary] => 20000.00
[PercentCharged] => 100
[MonthlySalary] => 54433.00
)
)
The Important Section starts where i need total number of days project has been assigned to certain employee..
If the whole month do get in the start and end date, then it would be 30 or 31 days but what if project has been assigned to employee in mid of month how would one can calculate total number of days then??

MySQL Replace string SUM then total

Looking to get a total for each ID from the sum of the replacement fields.
SELECT
insurance_carrier as ID, SUM(REPLACE(REPLACE(REPLACE(es_reserve,'$',''),',',''),'-','')) AS es_reserve,
SUM(REPLACE(REPLACE(REPLACE(structure_reserve,'$',''),',',''),'-',''))AS structure_reserve,
SUM(es_reserve+structure_reserve) AS total
FROM job_tbl
WHERE
job_status NOT IN(2,4,6,7,9) AND
insurance_carrier !=0 AND
FROM_UNIXTIME(date_of_loss,'%m') = MONTH(NOW()) AND
FROM_UNIXTIME(date_of_loss,'%Y') = YEAR(NOW())
GROUP BY insurance_carrier
I get the results from es_reserve and structure_reserve but the total is 0.
BTW the fields contain items like $2,300- that's the reason for the replace
Any help would be appreciated!!!
EDIT: here is the results this produces
Array
(
[ID] => 14
[es_reserve] => 5000
[structure_reserve] => 35000
)
Array
(
[ID] => 15
[es_reserve] => 2500
[structure_reserve] => 2500
)
Array
(
[ID] => 41
[es_reserve] => 2500
[structure_reserve] => 2500
)
Array
(
[ID] => 44
[es_reserve] => 2500
[structure_reserve] =>
)
Here is what I would like it to produce
Array
(
[ID] => 14
[es_reserve] => 5000
[structure_reserve] => 35000
[total] => 40000
)
Array
(
[ID] => 15
[es_reserve] => 2500
[structure_reserve] => 2500
[total] => 5000
)
Array
(
[ID] => 41
[es_reserve] => 2500
[structure_reserve] => 2500
[total] => 5000
)
Array
(
[ID] => 44
[es_reserve] => 2500
[structure_reserve] =>
[total] => 2500
)
Total column is doing sum on original column value , the alias name defined in the select won't be used in the same select.
You can repeat replace statement while doing total column computation
SUM( REPLACE(REPLACE(REPLACE(es_reserve,'$',''),',',''),'-','')
+ REPLACE(REPLACE(REPLACE(structure_reserve,'$',''),',',''),'-',''))
Total,
instead of
SUM(es_reserve+structure_reserve) as total
The query becomes, with order by as asked in comment.
SELECT insurance_carrier as ID, SUM(REPLACE(REPLACE(REPLACE(es_reserve,'$',''),',',''),'-','')) AS es_reserve, SUM(REPLACE(REPLACE(REPLACE(structure_reserve,'$',''),',',''),'-',''))AS structure_reserve, SUM( REPLACE(REPLACE(REPLACE(es_reserve,'$',''),',',''),'-','') + REPLACE(REPLACE(REPLACE(structure_reserve,'$',''),',',''),'-','')) as Total FROM job_tbl WHERE job_status NOT IN(2,4,6,7,9) AND insurance_carrier !=0 AND FROM_UNIXTIME(date_of_loss,'%m') = MONTH(NOW()) AND FROM_UNIXTIME(date_of_loss,'%Y') = YEAR(NOW()) GROUP BY insurance_carrier
order by SUM( REPLACE(REPLACE(REPLACE(es_reserve,'$',''),',',''),'-','') + REPLACE(REPLACE(REPLACE(structure_reserve,'$',''),',',''),'-','')) desc
OR
use it as subquery
SELECT T.*, SUM(es_reserve+structure_reserve) AS total
FROM
(
SELECT
insurance_carrier as ID, SUM(REPLACE(REPLACE(REPLACE(es_reserve,'$',''),',',''),'-','')) AS es_reserve,
SUM(REPLACE(REPLACE(REPLACE(structure_reserve,'$',''),',',''),'-',''))AS structure_reserve
FROM job_tbl
WHERE
job_status NOT IN(2,4,6,7,9) AND
insurance_carrier !=0 AND
FROM_UNIXTIME(date_of_loss,'%m') = MONTH(NOW()) AND
FROM_UNIXTIME(date_of_loss,'%Y') = YEAR(NOW())
GROUP BY insurance_carrier
) T

MySQL multiple SUM returning same value

I have a "bloomp" (like a post), when I select it from the database, I SUM the number of comments, likes and if the current user liked.
The problem is with the number of likes and comments. For example:
If the bloomp has 3 likes and 1 comment, the select return that it has 3 likes and 3 comments, and vice-versa.
Here's my query:
SELECT `bloomps`.`id` AS id,
`bloomps`.`text` AS text,
`bloomps`.`date` AS date,
`images`.`id` AS image_id,
`videos`.`id` AS video_id,
`videos`.`provider` AS video_provider,
`users`.`name` AS author_name,
`users`.`picture` AS author_picture,
SUM(CASE WHEN likes.bloomp_id IS NOT NULL THEN 1 ELSE 0 END) AS likes_number,
SUM(CASE WHEN likes.bloomp_id IS NOT NULL AND likes.author_id = 1 THEN 1 ELSE 0 END) AS liked,
SUM(CASE WHEN comments.bloomp_id IS NOT NULL THEN 1 ELSE 0 END) AS comments_number
FROM (`bloomps`)
INNER JOIN `users` ON `users`.`id` = `bloomps`.`author_id`
LEFT JOIN `likes` ON `likes`.`bloomp_id` = `bloomps`.`id`
LEFT JOIN `comments` ON `comments`.`bloomp_id` = `bloomps`.`id`
LEFT JOIN `images` ON `images`.`bloomp_id` = `bloomps`.`id`
LEFT JOIN `videos` ON `videos`.`bloomp_id` = `bloomps`.`id`
GROUP BY `bloomps`.`id`
ORDER BY `bloomps`.`id` ASC
LIMIT 10
This query:
SELECT `bloomps`.`id` AS id,
`bloomps`.`text` AS text,
`bloomps`.`date` AS date,
`users`.`name` AS author_name,
`users`.`picture` AS author_picture,
SUM(CASE WHEN likes.bloomp_id IS NOT NULL THEN 1 ELSE 0 END) AS likes_number,
SUM(CASE WHEN likes.bloomp_id IS NOT NULL AND likes.author_id = 1 THEN 1 ELSE 0 END) AS liked,
SUM(CASE WHEN comments.bloomp_id IS NOT NULL THEN 1 ELSE 0 END) AS comments_number
FROM (`bloomps`)
INNER JOIN `users` ON `users`.`id` = `bloomps`.`author_id`
LEFT JOIN `likes` ON `likes`.`bloomp_id` = `bloomps`.`id`
LEFT JOIN `comments` ON `comments`.`bloomp_id` = `bloomps`.`id`
GROUP BY `bloomps`.`id`
ORDER BY `bloomps`.`id` ASC
LIMIT 10
Is returning:
Array
(
[0] => Array
(
[id] => 1
[text] => All these years I've been feeling like I was growing into myself. Finally, I feel grown.
[date] => 0000-00-00 00:00:00
[image_id] =>
[video_id] => yfg8CMWeUAU
[video_provider] => youtube
[author_name] => Claudius Ibn
[author_picture] => 356a192b7913b04c54574d18c28d46e6395428ab.jpg
[likes_number] => 10
[liked] => 5
[comments_number] => 10
)
[1] => Array
(
[id] => 2
[text] => Reveal not every secret you have to a friend, for how can you tell but that friend may hereafter become an enemy. And bring not all mischief you are able to upon an enemy, for he may one day become your friend.
[date] => 0000-00-00 00:00:00
[image_id] => 356a192b7913b04c54574d18c28d46e6395428ab.jpg
[video_id] =>
[video_provider] =>
[author_name] => Elza Virginia
[author_picture] => 77de68daecd823babbb58edb1c8e14d7106e83bb.jpg
[likes_number] => 6
[liked] => 6
[comments_number] => 6
)
[2] => Array
(
[id] => 3
[text] => To me, old age is always 15 years older than I am.
[date] => 0000-00-00 00:00:00
[image_id] => 41025046575248278_WzB3wKD0_f.jpg
[video_id] =>
[video_provider] =>
[author_name] => Elza Virginia
[author_picture] => 77de68daecd823babbb58edb1c8e14d7106e83bb.jpg
[likes_number] => 1
[liked] => 1
[comments_number] => 0
)
[3] => Array
(
[id] => 4
[text] => Accept the pain, cherish the joys, resolve the regrets; then can come the best of benedictions - 'If I had my life to live over, I'd do it all the same.
[date] => 0000-00-00 00:00:00
[image_id] =>
[video_id] =>
[video_provider] =>
[author_name] => Claudio Cardozo
[author_picture] => da4b9237bacccdf19c0760cab7aec4a8359010b0.jpg
[likes_number] => 0
[liked] => 0
[comments_number] => 0
)
[4] => Array
(
[id] => 5
[text] => Be master of your petty annoyances and conserve your energies for the big, worthwhile things. It isn't the mountain ahead that wears you out - it's the grain of sand in your shoe.
[date] => 0000-00-00 00:00:00
[image_id] => 4889470_700b.jpg
[video_id] =>
[video_provider] =>
[author_name] => Claudius Ibn
[author_picture] => 356a192b7913b04c54574d18c28d46e6395428ab.jpg
[likes_number] => 1
[liked] => 1
[comments_number] => 0
)
[5] => Array
(
[id] => 6
[text] => I think we're having fun. I think our customers really like our products. And we're always trying to do better.
[date] => 0000-00-00 00:00:00
[image_id] =>
[video_id] =>
[video_provider] =>
[author_name] => Claudius Ibn
[author_picture] => 356a192b7913b04c54574d18c28d46e6395428ab.jpg
[likes_number] => 0
[liked] => 0
[comments_number] => 0
)
[6] => Array
(
[id] => 7
[text] => [Addiction's] not about placating the bad dog - it's about feeding the good dog. You still have to feed the bad dog, but only enough so that the ASPCA doesn't bring you up on charges.
[date] => 0000-00-00 00:00:00
[image_id] =>
[video_id] =>
[video_provider] =>
[author_name] => Claudius Ibn
[author_picture] => 356a192b7913b04c54574d18c28d46e6395428ab.jpg
[likes_number] => 0
[liked] => 0
[comments_number] => 0
)
[7] => Array
(
[id] => 8
[text] => I've been on a diet for two weeks and all I've lost is two weeks.
[date] => 0000-00-00 00:00:00
[image_id] =>
[video_id] =>
[video_provider] =>
[author_name] => Claudio Cardozo
[author_picture] => da4b9237bacccdf19c0760cab7aec4a8359010b0.jpg
[likes_number] => 1
[liked] => 1
[comments_number] => 0
)
[8] => Array
(
[id] => 9
[text] => A book burrows into your life in a very profound way because the experience of reading is not passive.
[date] => 0000-00-00 00:00:00
[image_id] =>
[video_id] =>
[video_provider] =>
[author_name] => Elza Virginia
[author_picture] => 77de68daecd823babbb58edb1c8e14d7106e83bb.jpg
[likes_number] => 1
[liked] => 1
[comments_number] => 0
)
[9] => Array
(
[id] => 10
[text] => Touch your customer, and you're halfway there.
[date] => 0000-00-00 00:00:00
[image_id] => 4878040_460s_v1.jpg
[video_id] =>
[video_provider] =>
[author_name] => Claudius Ibn
[author_picture] => 356a192b7913b04c54574d18c28d46e6395428ab.jpg
[likes_number] => 0
[liked] => 0
[comments_number] => 0
)
[10] => Array
(
[id] => 11
[text] => I know starting careers in troubled times is a challenge, but it is also a privilege. Because it's moments like these that force us to try harder, dig deeper and to discover gifts we never knew we had. To find the greatness that lies within each of us. So don't ever shy away from that endeavor. Don't stop adding to your body of work. I can promise that you will be the better for that continued effort as will be this nation that we all love.
[date] => 0000-00-00 00:00:00
[image_id] => 20547742019404735_U0zJkj83_f.jpg
[video_id] =>
[video_provider] =>
[author_name] => Elza Virginia
[author_picture] => 77de68daecd823babbb58edb1c8e14d7106e83bb.jpg
[likes_number] => 0
[liked] => 0
[comments_number] => 0
)
[11] => Array
(
[id] => 12
[text] => Misery no longer loves company. Nowadays it insists on it.
[date] => 0000-00-00 00:00:00
[image_id] =>
[video_id] =>
[video_provider] =>
[author_name] => Elza Virginia
[author_picture] => 77de68daecd823babbb58edb1c8e14d7106e83bb.jpg
[likes_number] => 0
[liked] => 0
[comments_number] => 1
)
[12] => Array
(
[id] => 13
[text] => A good novel tells us the truth about its hero; but a bad novel tells us the truth about its author.
[date] => 0000-00-00 00:00:00
[image_id] => 4887752_460s.jpg
[video_id] =>
[video_provider] =>
[author_name] => Elza Virginia
[author_picture] => 77de68daecd823babbb58edb1c8e14d7106e83bb.jpg
[likes_number] => 0
[liked] => 0
[comments_number] => 0
)
[13] => Array
(
[id] => 14
[text] => Acting is the most minor of gifts and not a very high-class way to earn a living. After all, Shirley Temple could do it at the age of four.
[date] => 0000-00-00 00:00:00
[image_id] =>
[video_id] =>
[video_provider] =>
[author_name] => Claudius Ibn
[author_picture] => 356a192b7913b04c54574d18c28d46e6395428ab.jpg
[likes_number] => 0
[liked] => 0
[comments_number] => 0
)
[14] => Array
(
[id] => 15
[text] => The time to repair the roof is when the sun is shining.
[date] => 0000-00-00 00:00:00
[image_id] =>
[video_id] =>
[video_provider] =>
[author_name] => Claudius Ibn
[author_picture] => 356a192b7913b04c54574d18c28d46e6395428ab.jpg
[likes_number] => 0
[liked] => 0
[comments_number] => 0
)
[15] => Array
(
[id] => 16
[text] => I am doomed to an eternity of compulsive work. No set goal achieved satisfies. Success only breeds a new goal. The golden apple devoured has seeds. It is endless.
[date] => 0000-00-00 00:00:00
[image_id] =>
[video_id] => 5431060
[video_provider] => vimeo
[author_name] => Claudio Cardozo
[author_picture] => da4b9237bacccdf19c0760cab7aec4a8359010b0.jpg
[likes_number] => 0
[liked] => 0
[comments_number] => 0
)
[16] => Array
(
[id] => 17
[text] => In every American there is an air of incorrigible innocence, which seems to conceal a diabolical cunning.
[date] => 0000-00-00 00:00:00
[image_id] => image18.png
[video_id] =>
[video_provider] =>
[author_name] => Claudius Ibn
[author_picture] => 356a192b7913b04c54574d18c28d46e6395428ab.jpg
[likes_number] => 1
[liked] => 1
[comments_number] => 0
)
[17] => Array
(
[id] => 18
[text] => Everything should be made as simple as possible, but not one bit simpler.
[date] => 0000-00-00 00:00:00
[image_id] =>
[video_id] =>
[video_provider] =>
[author_name] => Claudius Ibn
[author_picture] => 356a192b7913b04c54574d18c28d46e6395428ab.jpg
[likes_number] => 0
[liked] => 0
[comments_number] => 0
)
[18] => Array
(
[id] => 19
[text] => When I only begin to read, I forget I'm on this world. It lifts me on wings with high thoughts.
[date] => 0000-00-00 00:00:00
[image_id] =>
[video_id] =>
[video_provider] =>
[author_name] => Claudio Cardozo
[author_picture] => da4b9237bacccdf19c0760cab7aec4a8359010b0.jpg
[likes_number] => 0
[liked] => 0
[comments_number] => 0
)
)
You have joined more than one tables to the main (bloomps) table and all these have 1-to-many relationship with it. The result is a mini-cartesian join and wrong counts when grouping.
You need to group each one separately in subqueries and then join these to the base table - and no grouping there. Try this:
SELECT
b.id
, b.* -- whatever column from `bloomps`
, COALESCE(l.cnt,0) AS likes_number,
, COALESCE(l.liked,0) AS liked,
, COALESCE(c.cnt,0) AS comments_number
FROM
bloomps AS b
LEFT JOIN
( SELECT bloomp_id
, COUNT(*) AS cnt
, COUNT(CASE WHEN author_id = 1 THEN 1 END) AS liked
FROM likes
GROUP BY bloomp_id
) AS l
ON l.bloomp_id = b.id
LEFT JOIN
( SELECT bloomp_id
, COUNT(*) AS cnt
FROM comments
GROUP BY bloomp_id
) AS c
ON c.bloomp_id = b.id
-- no need for GROUP BY
ORDER BY id ASC
LIMIT 10 ;
If you don't want subqueries, you could keep the query with the modifications below. Test which one is more efficient:
SELECT
b.id
, b.test
, b.date
, COUNT(DISTINCT l.id) AS likes_number,
, COUNT(DISTINCT CASE WHEN l.author=1 THEN l.id END) AS liked,
, COUNT(DISTINCT c.id) AS comments_number
FROM
bloomps AS b
LEFT JOIN
likes AS l
ON l.bloomp_id = b.id
LEFT JOIN
comments AS c
ON c.bloomp_id = b.id
GROUP BY b.id ASC -- MySQL non-standard syntax for
-- GROUP BY b.id
-- ORDER BY b.id ASC
LIMIT 10 ;
The other joins are messing up your count. For example, let's say one bloomp has two videos and two comments; as currently written, your query will return 4 rows, making it looks like there are 4 comments. To fix it, either remove all the other stuff (see below), or add it to the Group By clause.
This should give you the basic info -- ID, as well as comments and likes:
SELECT `bloomps`.`id` AS id,
SUM(CASE WHEN likes.bloomp_id IS NOT NULL THEN 1 ELSE 0 END) AS likes_number,
SUM(CASE WHEN comments.bloomp_id IS NOT NULL THEN 1 ELSE 0 END) AS comments_number
FROM (`bloomps`)
LEFT JOIN `likes` ON `likes`.`bloomp_id` = `bloomps`.`id`
LEFT JOIN `comments` ON `comments`.`bloomp_id` = `bloomps`.`id`
GROUP BY `bloomps`.`id`
ORDER BY `bloomps`.`id` ASC
LIMIT 10
UPDATES :
SELECT table1.id, table1.likes_number, table2.comments_number FROM
(SELECT b.id AS id, SUM(IF(l.bloomp_id IS NULL,0,1)
FROM bloomps b LEFT JOIN likes l ON b.id = l.bloomp_id GROUP BY b.id) AS table1
JOIN
(SELECT b.id AS id, SUM(IF(c.bloomp_id IS NULL,0,1))
FROM bloomps b LEFT JOIN comments c ON b.id = c.bloomp_id GROUP BY b.id) AS table2
ON table1.id = table2.id
ORDER BY table1.id ASC
LIMIT 10;