I am looking for a SELECT query where I can find out the status of two users, status can be multiple things but let's keep it simple and check if both users are friends or not.
Using this query I can select every user that has x status, right now x means no status. But doing so I get the user table returned, I want the return to be true or false. Also, this query returns everyone that has x status with user x. I want to return true or false based on: if user x and x have a status, in this case friends. I hope I am not being to vague here.
SELECT
u.*
FROM User u
LEFT JOIN User_Status us
ON u.id = User_ID1
AND us.User_ID2 = 4
WHERE us.status IS NULL
User table:
ID-----first_name-----last_name-----etc...<br>**
-2--------James----------someting-------...<br>
-4----------Jack-----------someting-------...<br>
-5--------Sabrina---------someting-------...<br>
User_status table:
User_ID1-----User_ID2-----Status<br>**
-----------4-----------------2-----friends<br>
-----------2-----------------4-----friends<br>
-----------4-----------------5-----something else<br>
-----------5-----------------4-----something else<br>
Wanted result:
ID 2 (James) & ID 4 (Jack)
isFriend
true
ID 2 (James) & ID 5 (Sabrina)<br>
isFriend
false (They don't even have a status together.)
Indeed, your question is a little bit vague. Based on what I've understood, you want to find out if two users (known ID's) are friends or not?
The query below should help you with that.
SELECT
"A_USER_ID" as user_a,
"B_USER_ID" as user_b,
(
CASE
WHEN EXISTS(
SELECT *
FROM User_Status us
WHERE us.status = "friends" AND ((
us.User_ID1 = "A_USER_ID" AND us.User_ID2 = "B_USER_ID"
) OR (
us.User_ID1 = "B_USER_ID" AND us.User_ID2 = "A_USER_ID"
))
)
THEN "true"
ELSE "false"
END
) as friends
FROM
User u
WHERE
u.id = "A_USER_ID";
Related
thank you all for taking the time to read and help if you can! I have a query below that is getting large and messy, I was hoping someone could point me in the right direction as I am still a beginner.
SELECT
DATE(s.created_time_stamp) AS Date,
s.security_profile_id AS Name,
COUNT(*) AS logins,
CASE
WHEN COUNT(s.security_profile_id) <= 1
THEN '1'
WHEN COUNT(s.security_profile_id) BETWEEN 2 AND 3
THEN '2-3'
ELSE '4+'
END AS sessions_summary
FROM session AS s
INNER JOIN member AS m
ON s.security_profile_id = m.security_profile_id
JOIN member_entitlement AS me ON m.id = me.member_id
JOIN member_package AS mp ON me.id = mp.member_entitlement_id
**JOIN member_channels AS mc ON mc.member_id = m.id**
where member_status = 'ACTIVE'
and metrix_exempt = 0
and m.created_time_stamp >= STR_TO_DATE('03/08/2022', '%m/%d/%Y')
and display_name not like 'john%doe%'
and email not like '%#aeturnum.com'
and email not like '%#trendertag.com'
and email not like '%#sargentlabs.com'
and member_email_status = 'ACTIVE'
and mp.package_id = 'ca972458-bc43-4822-a311-2d18bad2be96'
and display_name IS NOT NULL
and s.security_profile_id IS NOT NULL
**and mc.id IS NOT NULL**
GROUP BY
DATE(created_time_stamp),
Name
ORDER BY
DATE(created_time_stamp),
Name
The two parts of the query with asterisks are the two most recently added clauses and they skew the data. Without these, the query runs fine. I am trying get a session summary which works fine, but I only want the sessions of people who have a 'channel' created. Maybe mc.id IS NOT NULL is not the way to do this. I will share my query that shows me how many people have created channels. Essentially, I am trying to combine these two queries in the cleanest way possible. Any advice is greatly appreciated!
-- Users that have Topic Channels and Finished Set Up FOR TRIAL DASH**
select count(distinct(m.id)) AS created_topic_channel
from member m right join member_channels mc on mc.member_id = m.id
left join channels c on c.id = mc.channels_id
JOIN member_entitlement AS me ON m.id = me.member_id
JOIN member_package AS mp ON me.id = mp.member_entitlement_id
where title not like '# Mentions'
and member_status = 'ACTIVE'
and metrix_exempt = 0
and m.created_time_stamp >= STR_TO_DATE('03/08/2022', '%m/%d/%Y')
and display_name not like 'john%doe%'
and email not like '%#aeturnum.com'
and email not like '%#trendertag.com'
and email not like '%#sargentlabs.com'
and member_email_status = 'ACTIVE'
and display_name IS NOT NULL
and mp.package_id = 'ca972458-bc43-4822-a311-2d18bad2be96';
The metric I am trying to retrieve from the DB is how many users have created a channel and logged in at least twice. Thank you again and have a wonderful day!!
If id is the primary key of member_channels then it does not make sense to check if it is null.
If all you want is to check whether a member has a 'channel' created, then instead of the additional join to member_channels, which may cause the query to return more rows than expected, you could use EXISTS in the WHERE clause:
where member_status = 'ACTIVE'
and .......................
and EXISTS (SELECT 1 FROM member_channels AS mc WHERE mc.member_id = m.id)
I would guess your tables aren't at the same level of granularity. A member may have many sessions, and 0-many channels.
eg if member 123 has five sessions and creates three channels => 15 rows of data in this join.
To adjust for this, it's best practice to join on the same level of granularity. You could roll up sessions to the member level, channels to the member level, and then join both against members.
There are three tables (column names are in brackets):
1-user_table (user_id, social_site)
value in social_site -> fb, whatsapp, wechat
2-booking_confirm (booking_id)
3-payment_table (order_id, payment_status)
payment_status = "success" or "fail"
no of user | social site | no of payment successful
34 | fb | 10
"no of user": find count(user_id) with respect to "fb" and "payment" (when order_id = booking_id and payment_status="success")
There's no connection between USER_TABLE (your first table) and another two tables, so the following query certainly won't work, but might give you an idea of how to do it (once you manage to fix what's wrong).
select count(*)
from user_table u join ??? on ??? --> what goes here?
--
booking_confirm b join payment_table p on b.booking_id = p.order_id
where u.social_site = 'fb'
and p.payment_status = 'success'
I need help to formulate a query to calculate points based on user action.
There is a user table which stores user info and each user belongs to a specific category (User category). Each category has different levels (say level1, level2 etc..) and each level has a set of tasks(Task1,Task2...) to be completed. Each task can be performed multiple times. But points is calculated based on a maximum limit field.
Task 1 - 10 points ( Max:2 - Means user can perform this task N times but for point calculation it will be only counted twice )
Task 2 - 5 points ( Max:1 )
For example lets say User1 performs Task1 5 times, but for point calculation Task1 will only be counted 2 times , so total points is 20. This is similar for all tasks.
On completing each task the user gains N points and get upgraded to next level.
Please find below the table structure and query:
users
uid , uname , uc_id ( References User Category ) , ul_id (References user level and indicates current level of user )
user_category
uc_id ....
user_level
ul_id, uc_id (References User Category)
...
level_tasks
lt_id , ul_id (References User level) , lt_point, lt_max
user_tasks
ut_id, lt_id (References level task), uid (References user)
The below is the query i have tried so far :
SELECT uid, SUM(LT.lt_point/LT.lt_max) as TotalLevelPoints
FROM users AS U
INNER JOIN user_tasks AS UT ON UT.ut_user_id = U.id
INNER JOIN level_tasks AS LT ON LT.lt_id = UT.lt_id
INNER JOIN user_level AS UL ON UL.ul_id = LT.ul_id
INNER JOIN user_category AS UC ON UC.uc_id = UL.uc_id
WHERE UT.ut_status = 1 AND U.uid = 1 AND UL.ul_id = 1
GROUP BY U.uid
This gives all the sum without considering the max limit, how should i write so that sum is calculated on that column also.
Hope my question is clear enough.. Any help would be really appreciated.
I believe you will need to do this in 2 steps. First sum the points and compare to the maximums allowed for each task type. Once that is determined, sum those results for each user. e.g.
SELECT
u.uid
, SUM(user_task_points) AS user_task_points
FROM users AS u
INNER JOIN (
SELECT
ut.UT_user_id
, lt_id
, lt.LT_point
, lt.LT_max_times
, CASE WHEN SUM(lt.LT_point) > (lt.LT_point * lt.LT_max_times) THEN (lt.LT_point * lt.LT_max_times)
ELSE SUM(lt.LT_point)
END AS user_task_points
FROM user_tasks AS ut
INNER JOIN level_tasks AS lt ON ut.UT_rule_id = lt.LT_id
INNER JOIN user_level AS UL ON UL.ul_id = LT.ul_id
WHERE ut.UT_status = 1
AND ut.UT_user_id = 1
AND ul.ul_id = 1
GROUP BY
ut.UT_user_id
, lt_id
, lt.LT_point
, lt.LT_max_times
) AS p ON u.id = p.UT_user_id
GROUP BY
u.uid
;
There is some discrepancy between column names in schema and query you have provided. I have gone with schema.
Query is not tested. But this approach should work.
SELECT uid, SUM(LevelPoints) TotalLevelPoints
FROM ( SELECT U.uid, LT.lt_id, SUM((CASE WHEN COUNT(*) > lt_max THEN lt_max ELSE COUNT(*) END)*lt_point) LevelPoints
FROM users U
INNER JOIN user_tasks UT
ON U.uid = UT.uid
INNER JOIN level_tasks LT
ON UT.lt_id = LT.lt_id
GROUP BY U.uid, LT.lt_id
)
GROUP BY uid
I have a query below and i am using IF statement but it is not working .
"SELECT * FROM chat,user WHERE
IF(chat.seller_id='".$user_id."') THEN user.id=chat.buyer_id
ELSE IF(chat.buyer_id='".$user_id."') THEN user.id=chat.seller_id"
Try using CASE instead:
SELECT * FROM chat,user WHERE
CASE
WHEN chat.seller_id='".$user_id."' THEN user.id=chat.buyer_id
WHEN chat.buyer_id='".$user_id."' THEN user.id=chat.seller_id
ELSE user.id='something'
END
The else is in case you have any user id that is not a seller or buyer
you should try this :
SELECT * FROM chat,user WHERE user.id = CASE
WHEN chat.seller_id='".$user_id."' THEN chat.buyer_id
WHEN chat.buyer_id='".$user_id."' THEN chat.seller_id
ELSE user.id='something'
END
Isn't this functionally the same as:
"SELECT *
FROM chat c,user u
WHERE (c.seller_id = u.id AND c.buyer_id = ".$user_id.")
OR (c.buyer_id = u.id AND c.seller_id = ".$user_id.")"
The logic of your query could also be accomplished with a UNION:
"
SELECT *
FROM chat
JOIN user
ON user.id = chat.buyer_id
WHERE chat.seller_id = '".$user_id."'
UNION
SELECT *
FROM chat
JOIN user
ON user.id = chat.seller_id
WHERE chat.buyer_id = '".$user_id."'
";
You should test UNION vs CASE to see which is faster. Be aware that even if your CASE query is valid, you might still get errors testing it in older versions of phpMyAdmin as the parser had issues with CASE statements.
If you just want a list of other users a particular $user_id has bought or sold from, you might want to consider just querying user.* or even just specific user columns. The SELECT * on both tables leads me to think you want to pull chat history for $user_id, but you should also be aware that the logic you have here could grab chats of users that have bought from or sold to $user_id but are not necessarily with $user_id. Here is an example table:
chat_id buyer_id seller_id
1 4 6
2 2 6
3 4 9
4 6 4
5 1 4
6 6 5
7 9 2
8 2 4
If seller = 4, then buyer_id = [1,2,6] => chat_id [2,4,5,6,8]
If buyer = 4, then seller_id = [6,9] => chat_id [1,2,3]
Your results would include [1,2,3,4,5,6,8] even though user 4 was only a part of [1,3,4,5,8]
If you only want chats for $user_id, then you could use something like
SELECT *
FROM chat c
JOIN user u
ON (
c.seller_id = u.id
OR c.buyer_id = u.id
)
WHERE u.id = $user_id
Also, since you are string concatenating your queries, PLEASE read up and learn to use PDO and parameterized queries to protect yourself from SQL injection attacks.
I have a problem in my SQL Select , for example we have two users X and Y , user X want to see user Y Following so , when see his following ,
user Y want to know who users in user X (following) follow them
in this picture : https://i.imgsafe.org/d2b2d83886.png user with id :68 want to see users.id = 50 Following
SELECT users.id,users.username,
CASE WHEN follows.user_id = 68 THEN 1 END AS is_Follow
FROM users
LEFT JOIN follows
ON follows.follower_id = users.id
WHERE follows.app = 1 AND follows.user_id = 50
but this return me NULL :( what should i do ?!
Conditions on the right table of a LEFT JOIN should be on the ON clause and not on the WHERE clause :
SELECT users.id,users.username,
CASE WHEN follows.user_id = 68 THEN 1 ELSE -1 END AS is_Follow --Minus one value means NO.
FROM users
LEFT JOIN follows
ON follows.follower_id = users.id AND
follows.app = 1 AND
Another thing, what exactly are you checking? How many people follow user_id=68 ? Because by the name of the column it doesn't sounds like it.
EDIT: Try this:
SELECT users.id,users.username,
MAX(CASE WHEN follows.user_id = 68 THEN 1 ELSE -1 END) AS is_Follow --Minus one value means NO.
FROM users
LEFT JOIN follows
ON follows.follower_id = users.id AND
follows.app = 1 AND
GROUP BY users.id,users.username