Mysql + php : select count group by day and user - php

i have the tables below
USER COMMENT
--------------------- -----------------------
| id | name | id | user_id | date
--------------------- -----------------------
| 1 | joe | 1 | 1 | 2014-10-10
| 2 | jane | 1 | 1 | 2014-10-10
| 3 | ted | 1 | 3 | 2014-10-11
My aim is to create a stats comparaison chart. So i want to extract for each current week days, the number of comment added by each user.
The expected array
-----------------------------
2014-10-10
-----------------------------
joe | 2
jane | 0
ted | 0
------------------------------
2014-10-11
------------------------------
joe | 0
jane | 0
ted | 1
I did a simple left join query and double group by, but the result was not formatted like expected.
Maybe, i have to sort and merge results using php?!
Thank you for the help

What I would do is
Select User.name , Comment.date
From Comment Left Join User On Comment.user_id = User.id
Order By Comment.date Desc
This would return a list with user who commented + date.
Now I would parse the result set :-
$query = "query above";
$rowset = $db->fetchAll($query);
$result = array();
foreach ($rowset as $row) {
$result[$row['date']][$row[User]] += 1
}
This would give you an array
Date1
=>user1
=>count
=>user2
=>count
Date2
=>user3
=>count
=>user4
=>count

Here's my attempt:
SELECT c1.date, c1.name, COUNT(c2.date)
FROM (
SELECT DISTINCT c.date, u.name, u.id
FROM COMMENT c
CROSS JOIN USER u) c1
LEFT JOIN COMMENT c2
ON c1.id = c2.user_id AND c1.date = c2.date
GROUP BY c1.date, c1.id
The difficulty was to obtain a list of all users for each date, which I produced with the sub query c1.

Related

How can I check two conditions before inserting?

I have three tables:
// Posts
+----+----------+---------------+-----------+
| id | title | content | id_author |
+----+----------+---------------+-----------+
| 1 | title1 | content1 | 1234 |
| 2 | title2 | content2 | 5678 |
+----+----------+---------------+-----------+
// Users
+----+--------+--------+
| id | name | active |
+----+--------+--------+
| 1 | jack | 1 |
| 2 | peter | 0 |
| 3 | John | 1 |
+----+--------+--------+
// Votes
+----+---------+---------+
| id | id_post | id_user |
+----+---------+---------+
| 1 | 32 | 1234 |
| 2 | 634 | 5678 |
| 3 | 352 | 1234 |
+----+---------+---------+
Now I need to check two conditions before inserting a new vote into Votes table:
The id of author and what I have passed are the same? Posts.id_user = :author (I know I can do that by a FK, but I don't want)
The account of current user is active? Users.active = 1
Also here is my query:
INSERT INTO Votes (id_post,id_user)
SELECT ?,?
FROM Posts p
WHERE p.id_user = :author limit 1;
How can I add second condition Users.active = 1 to my query?
EDIT: Actually I'm trying to don't let people be able to vote who are inactive (active = 0). For example if SO bans men, then I cannot vote to post anymore, because I (current user) am banned. So I'm pretty sure $_SESSION['id'] should be used in the query.
INSERT INTO Votes (id_post,id_user)
SELECT p.id,u.id
FROM Posts p, Users u
WHERE p.id_user = :author
AND u.id = :user
AND u.active = 1 limit 1;
then you set parameter user equal to the current user id.
EDIT: I suppose id_user in table Votes must be the voter's id, not the author of the post (correct?), so I fixed the query eliminating the JOIN.
Use and with where
INSERT INTO Votes (id_post,id_user)
SELECT ?,?
FROM Posts p, Users u
WHERE p.id_user = :author and u.active = 1 limit 1;
INSERT INTO Votes (id_post,id_user)
SELECT p.id, u.id
FROM Posts p
INNER JOIN Users u ON 1 = 1
WHERE p.id_user = :author
AND u.id = :current_user_id
AND u.active = 1
LIMIT 1;

Mysql loop data from 2 table

I have 2 table as below:
Table 1: common_member
+-----------+-----------+
| uid | username |
+-----------+-----------+
| 1 | haha |
| 2 | walao |
| 3 | alamak |
| 4 | hero |
| 5 | theone |
| 6 | nobody |
+-----------+-----------+
Table 2: labour_slog
+--------------+-------------+--------------+-------------+
| uid | slaveid | masterid | bytime |
+--------------+-------------+--------------+-------------+
| 1 | 2 | 3 | 123456 |
| 4 | 5 | 6 | 456789 |
+--------------+-------------+--------------+-------------+
I fetch the data as script below:
$queryLabourSlog = DB::query("SELECT * FROM ".DB::table('labour_slog')." ORDER BY id desc");
while($rowLabourSlog = DB::fetch($queryLabourSlog)) {
$user_list_slog[] = $rowLabourSlog;
};
array_multisort($idss, SORT_DESC, $user_list_slog);
In my html, I use
<!--{loop $user_list_slog $value}-->{$value[uid]} on {$value[bytime]} forced hire {$value[masterid]}'s employee {$value[slaveid]}.<!--{/loop}-->
The html will display:
1 on 123456 forced hire 3's employee 2.
4 on 456789 forced hire 6's employee 5.
How do I join the Table 1's username data to get the loop display as below?
haha on 123456 forced hire alamak's employee walao.
hero on 456789 forced hire nobody's employee theone.
Thanks.
SELECT table_slog.*, u1.`name`, u2.`name` FROM `table_slog` LEFT JOIN `common_member` AS u1 ON `table_slog`.`uid`=u1.`uid` LEFT JOIN `common_member` AS u2 ON `table_slog`.`slaveid`=u2.`uid` LEFT JOIN `common_member` AS u3 ON `table_slog`.`masterid`=u3.uid ORDER BY `id` DESC
Something like that:
SELECT `uid_main`.`username` AS `main_username`,
`uid_main`.`uid` AS `main_uid`,
`uid_master`.`username` AS `master_username`,
`uid_master`.`uid` AS `master_uid`,
`uid_slave`.`username` AS `slave_username`,
`uid_slave`.`uid` AS `slave_uid`,
`ls`.`bytime` AS `bytime`
FROM `labour_slog` AS `ls`
LEFT JOIN `common_member` AS `uid_main` ON (`ls`.`uid` = `cm`.uid)
LEFT JOIN `common_member` AS `uid_master` ON (`ls`.`master_id` = `cm`.uid)
LEFT JOIN `common_member` AS `uid_master` ON (`ls`.`slave_id` = `cm`.uid)
ORDER BY `cm`.`uid` DESC

join one row from one mysql table to multiple row in second table

I have question about mysql queries. The story goes something like this: I have table in which I store information about college trips. This table has attributes about name of a trip, id of a trip and activity. Activity can be 0 or 1, depending if trip is still active (1) or inactive (0). In second table I have information about students that have applied for trips with attributes: id, name, surname and id of a trip that student have applied for. I don't know mysql query that will show me only students that have applied for trips that are still active (acitivity=1).
For example let's have a look at these tables:
TRIPS
id | trip | activity
---+----------+-----------
1 | Paris | 0
2 | London | 1
3 | Belgrade | 0
4 | Prague | 1
STUDENTS
id | name | id_trip
---+----------+-----------
1 | Mark | 3
2 | Ana | 1
3 | Tom | 2
4 | Maya | 3
5 | Rachel | 4
6 | John | 2
RESULT
id | name | id_trip | trip | activity
---+----------+---------+---------+---------
3 | Tom | 2 | London | 1
5 | Rachel | 4 | Prague | 1
6 | John | 2 | London | 1
SELECT
s.id,
s.name,
s.id_trip,
t.trip,
t.activity
FROM
STUDENTS AS s
INNER JOIN TRIPS AS t ON ( t.id = s.id_trip )
WHERE
t.id = 1
hope this will work.
Try this:
SELECT s.id, s.name, s.id_trip, t.name, t.activity
FROM students s
JOIN trips t
ON s.id_trip = t.id
WHERE t.activity = 1
select * from students s
join trips t
on s.id_trip = t.id
where t. activity =1
Try this it may solve your problem:
select s.id as id, s.name as name,t.trip as trip,
t.activity as activity from trips t
join students s on
t.id = s.id_trip
where t.activity = 1

Insert `COUNT(*)` based on separate table

In MySQL is it possible to select columns from one table while also creating a column for COUNT(*) based on other tables? That way a summary of the results from all tables can be returned. This might be a bit confusing to explain in words so I made some sample tables instead:
events_tbl
----------------------------
id | eventname
1 | Anime Festival
2 | Food Festival
----------------------------
booths_tbl
-------------------------
id | boothname
1 | Walmart
2 | Pizza Hut
3 | Nike
4 | North Face
-------------------------
participants_tbl
-----------------------------
id | participantname
1 | John
2 | Mike
3 | Rambo
4 | Minnie
-----------------------------
event_booths_tbl
--------------------------------
event_id | booth_id
1 | 1
1 | 2
1 | 5
2 | 3
2 | 4
--------------------------------
event_participants_tbl
-------------------------------------
event_id | booth_id
1 | 1
1 | 2
1 | 3
1 | 4
-------------------------------------
Is there a way to get results like this in MySQL:
summary_tbl
------------------------------------------------------------------------
id | eventname | booth_count | participant_count
1 | Anime Festival | 3 | 4
2 | Food Festival | 2 | 0
------------------------------------------------------------------------
The event_participants_tbl should contain participant_id instead of booth_id.
Its irrelevant otherwise.
Your MySQL query would be like this :
select
et.id,
et.eventname,
count(distinct ebt.booth_id) as booth_count,
count(distinct ept.participant_id) as participant_count
from
event_booths_tbl ebt
left join events_tbl et on et.id=ebt.event_id
left join event_participants_tbl ept on ept.event_id=ebt.event_id
group by et.event_id;
Join with subqueries that count in each table:
SELECT e.id, e.event_name,
IFNULL(b.booth_count, 0) AS booth_count,
IFNULL(p.participant_count, 0) AS participant_count
FROM events_table AS e
LEFT JOIN (SELECT event_id, COUNT(*) AS booth_count
FROM event_booths_table
GROUP BY event_id) AS b ON e.id = b.event_id
LEFT JOIN (SELECT event_id, COUNT(*) AS participant_count
FROM event_participants_table
GROUP BY event_id) AS p ON e.id = p.event_id
Try this :
select event.id,
event.name,
count(distinct eventBooth.booth_id),
count(distinct eventParitcipant.booth_id)
from events_tbl event
LEFT JOIN event_booths_tbl eventBooth on eventBooth.event_id=event.id
LEFT JOIN event_participants_tbl eventParitcipant
on eventParitcipant.event_id=event.id
group by event.id

Record that haven't relationship with other table

i have two tables: users and user_visits.
For example i would get the user_id and name of users that have 0 visited where date > '2014-05-06' and date < '2014-05-11'.
USERS TABLE USERS_VISITS TABLE
USER_ID | NAME USERS_VISIT_ID | USER_ID | DATE
1 | John 1 | 1 | 2014-05-07
2 | Mark 2 | 1 | 2014-05-08
3 | Mike 3 | 4 | 2014-05-10
4 | Steven
The result must be:
USER_ID | NAME | COUNT(*) |
2 | Mark | 0 |
3 | Mike | 0 |
My query is:
SELECT COUNT(uv.user_id) AS count_visited,
FROM users u
LEFT JOIN users_visited uv ON (u.user_id=uv.user_id)
WHERE uv.date >= '2014-05-06'
AND uv.date <= '22014-05-11'
GROUP BY u.user_id
HAVING count_visited = 0;
This is how you can do it using left join
select
u.user_id,
u.name
from user u
left join user_visits uv on uv.user_id = u.user_id
AND uv.date >= '2014-05-06'
AND uv.date <= '22014-05-11'
where uv.user_id is NULL

Categories