I have three tables that I use which has proved this problem to be way out of my league.
The first is the hierachy table which looks like this
USER_ID, USER_LEVEL, Store_Manager_ID, Team_Manager_ID
------------------------------------------------------
1, 0, -, -
2, 1, 1, -
3, 2, 1, 2
4, 2, 1, 2
5, 2, 1, 2
This just shows the hierachy of the user. So user 1 has a level of 0 which means he is th store manager and so he has no store manager on top of him so his store manager id is nothing and team manager is obviously nothing.
The second user is the team manager and so level = 1 and store manager is 1(the first guy)
The third, forth and fifth are workers under 1 and 2 respectively.
The second is a login table which looks like this
USER_ID, EMAIL
--------------------------
1, john.smith#gmail.com
2, ron.jones#gmail.com
3, tom.graham#gmail.com
4, bill.small#gmail.com
The email is the login, no password.
The third is an alias table which looks like this
USER_ID, ALIAS_ID
--------------------
2, 5
The alias tables shows how user 5 is an alias of user 2. So he is the same person and has the same login. However he can be in two places in the hierachy at once i.e. a team manager and a worker at the same time.
My question is.
If I know that user 2 will be logging in as his alias, i.e. a worker before login.
When user 2 logs in, how can I select the id of the leader of the users account based on the level.
For example if I logged in as ron.jones#gmail.com (user 2) under my alias account.
The alias id of user 2 is 5 and based on the hierachy user 5 is level 2 i.e. a worker and so I should return the id of his team manager not his store manager.
So I would then return 2, i.e. himself (a little bizarre in the this case but besides the point)
This will give the answer you are looking for (if I understand the question correctly):
SELECT team_manager_id
FROM hierarchy h
INNER JOIN aliases a ON h.user_id = a.alias_id
INNER JOIN login l ON a.user_id = l.user_id
WHERE email = 'ron.jones#gmail.com';
Select user_ID, User_level, Store_Manager_ID, Team_Manager_ID
FROM Hierachy H
INNER JOIN Alias A on A.Alias_ID = H.User_Id
Where A.User_ID = 2
Assumes: that 1 a user doesn't have more than 1 alias, if it does you'll get multiple records back for the same user.
Assumes you don't carea bout the record 2 in hierachy as all you're after is 5.
If I understand correctly, you want the managers of a user, either based on the user or the alias for the user.
The following query does two joins, one to the user table and one to the alias table:
SELECT team_manager_id
FROM h.user_id = a.alias_id INNER JOIN
login l
ON a.user_id = l.user_id join
hierarchy huser
on huser.user_id = a.alias_id join
hierarchy halias
on halias.user_id = l.user_id
WHERE l.email = 'ron.jones#gmail.com' and
huser.team_manager_id is not null and
halias.team_manager_id is not null
It also checks that the manager is not null, returning only managers on the alias. This returns all such managers. Do you need a particular one, say from the lowest level of the hierarchy?
Related
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.
(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;
Summary of problem: I have a CakePHP/MySQL web application. Users do quizzes to be awarded badges. Each quiz has a level (1 up to 5) to represent difficulty (1 = Easy, 5 = difficult).
I have 3 tables:
quizzes : A series of quizzes, each of which have a difficulty level 1 - 5 (quizzes.test_level) field and a unique ID (quizzes.id).
badge_structure : A list of quizzes which are required to gain a particular badge. Foreign key to 'quizzes' is badge_structure.quiz_id. This table contains multiple quizzes at each test_level.
results : A list of users results for a particular quiz. Foreign key is results.quiz_id. There is also a results.user_id to link to a 'users' table. Results are only stored in this table if the user has passed a quiz: If there is no results.quiz_id in this table for a given user, that user has not passed a particular quiz.
The problem I'm facing is I cannot work out which level the user has passed.
My application needs to show a star rating (1 - 5) based on quiz results for a given user. They must have completed all quizzes at a particular level (quizzes.test_level) to be awarded the star for a given badge, i.e.
quizzes.test_level = 1 (1 star)
quizzes.test_level = 2 (2 stars)
For the code below assume badge_structure.id = 3 (Badge number 3) and user.id = 257
SELECT MAX(q.test_level) AS badge_level
FROM badges_structure bs
JOIN quizzes q ON bs.quiz_id = q.id
JOIN results r ON bs.quiz_id = r.quiz_id
WHERE bs.badge_id = 3 AND r.user_id = 257
ORDER BY q.test_level ASC
This will give me the maximum test_level of a quiz a user has done, for a given badge. But I don't know whether they have passed that level, I only know that they have done quizzes that are within that level.
If I run something like this:
SELECT bs.badge_id, bs.quiz_id, q.test_level
FROM badges_structure bs
LEFT JOIN quizzes q ON bs.quiz_id = q.id
LEFT JOIN results r ON bs.quiz_id = r.quiz_id
WHERE bs.badge_id = 3 AND r.user_id = 257
ORDER BY q.test_level ASC
I can see the quizzes and levels they have done, but it doesn't tell me the whole badge_structure for that badge, because it's not including rows where they haven't yet got results.
How is it possible to see the badge structure and have a column which is 'null' if the user has no quiz results for a particular quiz ID?
Requirements:
1. All "Users" have 5 fixed set of same "Services" which they are supposed to rate.
2. Given the userId, display all the Services and their corresponding "Ratings".
3. Rating would be from a scale of 1 - 5 only
4. Ratings can be updated anytime by the user for any of his Service.
I am no SQL/DB expert and I had this question up in stacks for which I got answer from Raj here ER Model of User Ratings
This is the ER I finalized (open for correction).
My Fetch Query: Get all the services and their corresponding for a userId (say userId = 1)
SELECT service.service_id, service.name, usr.ratings
FROM services service,
ratings ratings,
userservices_ratings usr,
user user,
user_services us
where
us.userid = user.uid and
us.serviceid = service.serviceid and
usr.usid = us.id and
usr.rid = ratings.rid and
user.id = 1
The above query will return all the services and ratings, only if User has rated the service. For services which are unrated don't make it to result set. So I assume I should pre-populate unrated services with a default value say 0?
All users will have fixed set of 5 services all the time, do I write a trigger to create his entry into User_Services table whenever a User is created?
How would the create/update query look if for example a Userid = 1, rates = 3 for serviceId = 1?
Any flaw in the schema?
You can standard format of Rating Schema here https://schema.org/Rating
You can pick required columns from this
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!