how to select specific rows in some condition - mysql

I tried to write a query that selects rows with steps that both user 1 and user 2 did, with combined number of times they did the step (i.e., if user 1 did step 1 3 times and user 2 did 1 time then the count should show 4 times.)
when I put condition as user_id=1, user_id=2 there is no error but it return nothing, when it should return some rows with values.
there is table step, and step taken
and table step has column id, title
table step_taken has column id, user_id(who performs steps), step_id
i want to find step that both of two user whose id 1,2 did
and also want to have the value as count added up how many times they performed that step.
for example if user id 1 did step named meditation 2 times,
and user id 2 did step named meditation 3 times,
the result i want to find should be like below ;
------------------------------
title | number_of_times
------------------------------
meditation| 5
------------------------------
here is my sql query
select title, count(step_taken.step_id)as number_of_times
from step join step_taken
on step.id = step_taken.step_id
where user_id = 1 and user_id=2
group by title;
it returns nothing, but it should return some rows of step both user1 and user 2 did.
when i wrote same thing only with user_id=1 or user_id=2, it shows selected information
how can I fix my code so it can show the information I want to get?
thanks in advance :)

user_id cannot be 1 and 2 at the same time. You need a second user table. Then join those on your criteria and count:
select title, count(u1.id) + count(u2.id) as number_of_times
from step u1 join step u2
on u1.id = u2.id
where u1.user_id = 1 and u2.user_id=2
group by title;
note: cannot tell what table title is in, or the purpose of step_taken was as step.id is identical.

Related

Count Unique Values Throughout One Day For Nonconsecutive Student ID's

I am trying to figure out how to count all instances where a student is online without counting duplicate instances.
For example, in the screenshot below, I want to see a column counting only instances where a student is logged in. So, if Student A is logged in at 5 AM, count = 1. Student B logged in at 7, Count = 2. At some point student A logged off and logged back on at 8 am, the count should be 2, not 3.
Thank you!
Student
Time.
Desired Column (Count)
A
5 AM
1
B
7 AM
2
A
8 AM
2
C
9 AM
3
D
10 AM
4
E
11 AM
5
D
12 PM
5
I am mainly trying to track the activity and only count when someone is logged in. If those students appear multiple times, we can assume they logged off at some point and logged back in. It's basically a unique running count. Not sure how to write this in SQL. I hope this makes sense.
One option, use the exists operator with a correlated subquery to check if the student has logged in before:
SELECT Student, Time_,
SUM(flag) OVER (ORDER BY Time_) AS expected_count
FROM
(
SELECT *,
CASE
WHEN EXISTS(SELECT 1 FROM table_name D WHERE D.Student = T.Student AND D.Time_<T.Time_)
THEN 0 ELSE 1
END AS flag
FROM table_name T
) D
ORDER BY Time_
See demo.

Getting X results from SQL with multiple tables

(Sorry for my bad english, I'll try to be the clearest)
I want to select 5 conversations (over an undetermined number, there could be 5 or 300 conversations) of one user in a MySQL table, and for each of those, I want to select all the users who talk in it.
In a wonderfull world, I'd like to do it with one query.
My query looks like (tables are in french, plz don't hurt me) :
SELECT mc.mc_id, mc.mc_sujet, mc.mc_statut,
miu.mi_ustatut as uself_statut, miu.mi_datelecture as uself_datelecture,
mi.mi_uid, mi.mi_ustatut, mi.mi_datelecture,
u.u_pseudonyme
FROM msg_individus as miu
LEFT JOIN msg_conversations as mc ON mc.mc_id = miu.mi_mcid
LEFT JOIN msg_individus as mi ON mi.mi_mcid = mc.mc_id
LEFT JOIN u_individus as u ON u.u_id = mi.mi_uid
WHERE miu.mi_uid = :u_id
Where msg_individus is the table with participants of a conversation,
msg_conversations is the table of the conversation (id, subject, status),
u_individus is the table with users' informations.
To select only 5 of those conversations, I added something like
GROUP BY mc.mc_id,
LIMIT 0,5
But of course, only one user per conversation is given is this way.
I also tried to write GROUP BY mc.mc_id, mi.mi_uid but this, like no writting a GROUP BY condition, returns 5 iterations like :
(Conversation 1 has two users, conversation 2 has one, conversation 3 has four)
Iteration 1 : conversation 1, user 1
Iteration 2 : conversation 1, user 2
Iteration 3 : conversation 2, user 1
Iteration 4 : conversation 3, user 1
Iteration 5 : conversation 3, user 2
What I want is to get five CONVERSATIONS with all their datas (whatever the number of users in it, etc)
I guess I'll have to use two queries (after getting the 5 conversations, I'll get the users per conversations), but maybe you guys can light me with your knowledges.
Thx.
Use a subquery to get five conversations. I also suggest that you replace the outer joins with inner joins. I think the table keys should all have matches:
SELECT mc.mc_id, mc.mc_sujet, mc.mc_statut,
miu.mi_ustatut as uself_statut, miu.mi_datelecture as uself_datelecture,
mi.mi_uid, mi.mi_ustatut, mi.mi_datelecture,
u.u_pseudonyme
FROM (SELECT miu.*, mc.*
FROM msg_individus miu JOIN
msg_conversations mc
ON mc.mc_id = miu.mi_mcid
WHERE miu.mi_uid = :u_id
ORDER BY rand() -- not necessary, but why not?
LIMIT 5
) ic
msg_individus mi
ON mi.mi_mcid = ic.mc_id JOIN
u_individus u
ON u.u_id = ic.mi_uid;

Join from two tables mysql

I have a doubt where trying to join two tables by a previous search. I've looked several solutions and read some chapters in a mysql book but I think I'm pretty close to the right answer but still not get it
I have this table "userprocess":
idProcess username state
------------------------------------------
1 blisssing 3
2 enriquecalvera 1
2 africabaluja 2
1 enriquecalvera 3
2 blisssing 1
The primery key for this table is the union of idProceso+username.
I have this other table "user":
index username pass active tipeUser .... so on
----------------------------------------------------------------- ----
1 blisssing 6OiZVVUPi3LDE 1 user
2 carmen 6OOtfrXB2Nu5. 1 user
3 consuelo 6OgdhVSkr1VDs 1 user
4 africabaluja 6OoPtGjWMQARE 1 user
5 enriquecalvera 6O6tvHg.122uQ 1 user
The thing is I want to show the join of the two tables but with a search within the first table. If I run this query
SELECT username FROM userprocess where idProcess='1' ORDER BY state
I get this:
username
---------
blisssing
enriquecalvera
which is what I am looking for, but I want to show all the fields in the "user" table for those usernames ordered by idProceso. So I run this other query:
SELECT *
FROM
user u,
userprocess p
WHERE
u.username=p.username
AND u.username IN (
SELECT username
FROM userprocess
where idProcess='1'
ORDER BY username
) ORDER BY p.state
I got this:
username pass active tipeUser idProcess state
----------------------------------------------------------------------
blisssing 6Od3nSkfOiwlg 1 user 2 1
enriquecalvera 6Oc9usiDEk51U 1 user 2 1
enriquecalvera 6Oc9usiDEk51U 1 user 1 3
blisssing 6Od3nSkfOiwlg 1 user 2 3
But this is not what I want I just want the same two results as in the previous query but with all the columns of the result of joining the two tables..
I know there is a lot of questions like this, but I have tried a lot of things and still not having the desire result..
What am I missing?
thank you, if you have any qestion or doubt just ask :)
The reason you're seeing multiple results is because you're joining on just the username, but of course the userprocess table has 2 rows where username = enriquecalvera. Your subquery is correctly only returning the 1 row you're interested in (where idprocess = 1) but as your join is seperate to this, and therefore doesn't include the idprocess = 1 condition, you're getting both rows back.
You should just do this in one step with a join like this:
SELECT *
FROM
user u
INNER JOIN userprocess p on u.username=p.username and p.idProcess='1'
ORDER BY p.state

MYSQL - How to check if a user is following another user, potentially through a subselect?

I'm fetching a list of activities (activities) and using a left join to grab the user data (users) who created the activity. Within my application users have the ability to follow one another.
This is my current query, which grabs all activities not posted by yourself ($user_id)
SELECT
activities.id, activities.user_id, users.id, users.name
FROM
activities
LEFT JOIN
users on activities.user_id = users.id
WHERE
users.id != $user_id
Aside from the activities + users tables, I have a another table in my application called followers:
followers
id | user_id_1 | user_id_2 | followed_back
1 1 3 1
2 2 3 0
3 3 1 1
I need to check whether you ($user_id) have followed a particular user joined to each activity and perhaps call this new field "user_followed" which represents a true/false/null value?
For example, I'm user_id = 1. Based on the above table, this means I have followed user_id 3. When an activity is fetched and user_id 3 is joined / responsible, the new field "user_followed" would be true.
Therefore, I think I'd need to incorporate another SELECT query, checking if the user is being followed:
(SELECT
*
FROM
followers
WHERE
user_id_1 = $user_id AND user_id_2 = users.id
)
I'm just largely unsure of how to incorporate this into my initial query and create a new field representing yes or no. Any help would be much appreciated!

How to SELECT MySQL 1-to-LAST on 1-to-Many Relationship

I have 2 Tables -- Table 1 is a master file and Table 2 is an activity file.
The relationship is 1-to-Many.
I am producing a report and all I want to return is every master file row joined to only the last activity row for the related master id.
I am unsure on how to request the last activity row. My code below returns every activity row (rightfully so).
Thank you for your help.
SELECT *
FROM master_file AS master
INNER JOIN activity_file AS activity ON activity.id = master.id
ORDER BY master.display_name
The activity file has a column called entry_date. It is a date and time stamp recording every activity. I simply want to select the last entry_date.
For example:
Table 2 - Activity looks like this
ID ACTIVITY ENTRY_DATE
1 Update 2012-08-01 09:00:00
1 Edit 2012-08-01 13:45:15
3 Create 2012-07-15 10:09:52
3 Delete 2012-07-22 23:02:00
3 Add 2012-08-05 04:33:00
4 Edit 2012-08-03 15:12:00
One standard way to solve this is to create an inline view that finds the last entry_date per ID.
SELECT *
FROM master_file AS master
LEFT JOIN activity_file AS activity ON activity.id = master.id
LEFT JOIN (select id , max(entry_date) entry_date
From activity_file
group by id) last_activity
ON activity_file.id = last_activity.id
and activity_file.entry_date= last_activity.entry_date
ORDER BY master.display_name
The one problem with this approach is that you may have more than one record with max(entry_date) for a given id. You'll either need to have your business rules handle this (e.g. simply display more than one record for that case) or you'll need to figure out a tie breaker. The last thing you want is to make it non-deterministic