How to get unique id's data among the same score - sql

The records in the table likes:
user score label
----------------------------------------------
userA 2 apple
userA 2 banana
userB 5 cat
userB 5 dog
For different rows, if the user and score are same, it just need to get the unique user and score, and any label is fine.
The expected query result from above is example can be any one as below:
user score label
----------------------------------------------
userA 2 apple
userB 5 cat
or
user score label
----------------------------------------------
userA 2 banana
userB 5 cat
or
user score label
----------------------------------------------
userA 2 apple
userB 5 dog
or
user score label
----------------------------------------------
userA 2 banana
userB 5 dog

if any label is fine, I think the easiest way is to use an aggregation function like min or max --
SELECT user, score, max(label) as label
FROM table
GROUP BY user, score

you can use window function:
select * from
(
select * , row_number() over (partition by user,score order by label) rn
from tablename
) t
where t.rn = 1;

Related

Get list of user who are involved in conversation

My "users" table is like this
id name
1 UserA
2 UserB
3 UserC
4 UserD
And my "chats" table is like this
id text sentBy sentTo created
1 Hi UserB 1 2 2019-01-11
2 Hi 2 1 2019-01-12
3 Hi UserB 3 2 2019-01-13
4 Hello UserC 2 3 2019-01-14
5 Hello 3 2 2019-01-15
6 What u do 2 1 2019-01-16
7 Nothing 1 2 2019-01-17
8 Okay 2 1 2019-01-18
8 Hi UserA 3 1 2019-01-19
I want to show user list who is involved in a conversation with logged in user based on the last msg.
Like if UserA logged in the system then the list should be like
userId userName text created
3 UserC Hi UserA 2019-01-19
2 UserB Okay 2019-01-19
I tried by using a join query and group by but not succeed.
I am using PostgreSQL with koa js.
You may use DISTINCT ON to filter out all apart from the most recent record for each involved in the conversation.
SELECT DISTINCT ON( involved) involved AS userid,
u.NAME AS username,
text,
created
FROM (SELECT c.*,
CASE sentby
WHEN 1 THEN sentto
ELSE sentby
END AS involved
FROM chats c
WHERE c.sentby = 1
OR c.sentto = 1) s
JOIN users u
ON s.involved = u.id
ORDER BY involved,
created DESC
Demo
If you want a generic case, you may convert this to a SQL type Postgres function and pass userid as an argument and use it in place of 1.
To get a complete list of users involved in the last conversation of the $current_user, with the last message (sent or received) and its date (created):
WITH u1 AS (SELECT id FROM users WHERE name = $current_user)
SELECT DISTINCT ON (userId) *
FROM (
SELECT u.id AS userId, u.name AS userName, c.text, c.created -- received
FROM u1
JOIN chats c ON c.sentBy = u1.id
JOIN users u ON u.id = c.sentTo
UNION ALL
SELECT u.id, u.name, c.text, c.created -- sent
FROM u1
JOIN chats c ON c.sentTo = u1.id
JOIN users u ON u.id = c.sentBy
) sub
ORDER BY userId, created DESC;
I separated into two UNIONed SELECTs, to make the most of two separate indexes on chats - one with leading sentTo, one with leading sentBy. Just updated a closely related answer yesterday:
Finding all rows with unique combination of two columns
About DISTINCT ON:
Select first row in each GROUP BY group?
Might be optimized in various ways, depending on undisclosed information.

SQL Select Where

i have a table like this
UserFriends
Id UserId RequestId Status
1 1 2 1
2 1 3 1
3 1 4 0
4 3 2 1
5 3 4 1
basically the structure is if status is 0 request not accepted else 1 accepted and they are friends
i am trying to do get user 2 friends how can i do ?
IMPORTANT EDIT:
i am trying to get user 3's friends. you know if user 1 added user 3 they are friends and user 3 added 2 and 4 they friends too (user 3 friends must return 1, 2 and 4 this is basic explanation)
If I read correctly, a friendship is characterized by either a user inviting another user or by that user being invited by other users, and in both cases the request was accepted. If so, then the following UNION query should give the expected results:
SELECT RequestId
FROM UserFriends
WHERE UserId = 3 AND Status = 1
UNION
SELECT UserId
FROM UserFriends
WHERE RequestId = 3 AND Status = 1
I use a UNION here because a given user could appear as a friend more than once if a pair of users invited each other, or if an invitation were sent more than once. I am assuming that you don't want to report the same user as a friend more than once.
Output:
Demo here:
Rextester

SQL Server 2012 LIMITing query

Okay so I need to make an SQL query that will perform the same as this MySQL query
SELECT DISTINCT userID
FROM gallery
ORDER BY userID ASC
LIMIT 0, 3
The SQL query that I have now looks like this, but it won't do the same job because of the second row still having the userID
SELECT DISTINCT TOP 3 userID
FROM gallery
WHERE imageID NOT IN (
SELECT TOP 1 imageID
FROM gallery
ORDER BY userID
)
ORDER BY userID;
The table looks something like this
imageID userID albumID
---------------------------
1 user1 2008
2 user1 2008
3 user1 2008
4 user1 Wild Fees
5 user1 Wild Fees
6 user1 Wild Fees
7 user1 Wild Fees
8 user1 Billfish 15000
9 user1 Billfish 15000
10 user1 Billfish 15000
11 user1 Billfish 15000
12 user1 2009
13 user1 2009
14 user1 2009
15 user2 New Album Name 001
16 user2 New Album Name 001
17 user2 New Album Name 001
18 user2 New Album Name 001
19 user2 New Album Name 001
20 user2 New Album Name 001
21 user2 New Album Name 001
22 user2 New Album Name 001
23 user2 New Album Name 001
24 user2 New Album Name 001
25 user2 New Album Name 001
26 user3 qweee
27 user3 qweee
28 user3 qweee
29 user3 qweee
=== EDIT ===
The expected output of this specific SQL is
|userID|
--------
|user2 |
|user3 |
Use the new offset functions in 2012:
SELECT DISTINCT userID
FROM gallery
ORDER BY userID ASC
OFFSET 0 ROWS
FETCH NEXT 3 ROWS ONLY;
I have not used MYSQL, so not sure whether your MYSQL query skips the 1st row or not. PLease double check that.
And if you really want to take out the top user id, you can try this one.
SELECT DISTINCT TOP 3 userID
FROM gallery
WHERE userID NOT IN (
SELECT TOP 1 userID
FROM gallery
ORDER BY userID
)
ORDER BY userID;
Thanks
SELECT DISTINCT TOP 3 userID
FROM gallery
WHERE userID NOT IN (
SELECT TOP 1 userID
FROM gallery
ORDER BY imageID
)
ORDER BY userID;
Try this version:
SELECT TOP 3 userID
FROM gallery
GROUP BY userID
ORDER BY userID ASC ;
EDIT: (based on getting rows 2-4 rather than 1-3)
In SQL Server 2012, you can use offset and fetch:
SELECT userID
FROM gallery
GROUP BY userID
ORDER BY userID ASC
OFFSET 1 ROWS FETCH NEXT 3 ROWS ONLY;

Grouping results in sql query by a field in the result

I have a table with the following format:
User | Entity | ID
123 AB 1
123 AB 2
543 BC 3
098 CB 4
543 BC 5
543 ZG 6
etc...
I want to get a result set that only returns the User/Entity pairs and their ID for the greatest ID, so this result for example:
User | Entity | ID
123 AB 2
098 CB 4
543 BC 5
543 ZG 6
Is there any way to do this in SQL?
Try to use group by with max function
select user, Entity, max(id) as id
from table
group by user, Entity
You can also use CTE and Partition By
Like this:
;WITH CTE as
(
SELECT
Users,Entity,
ROW_NUMBER() OVER(PARTITION BY Entity ORDER BY ID DESC) AS Row,
Id
FROM Item
)
SELECT Users, Entity, Id From CTE Where Row = 1
Note that we used Order By ID DESC as we need highest ID. You can delete DESC if you want the smallest ID.
SQLFiddle: http://sqlfiddle.com/#!3/1dcb9/4

Twitter style following-follower table in SQL-2

Addition to this Twitter style following-follower table in SQL
In the upper example I was able to return the query for "if userB is following the other users who follows him"
I need a simpler thing now. I tried to modify the original code without any luck. I simply need "if userB is following or not any of the users , regardless if they follow him. Currently it returns null for people who dont follow that particular user.
This is the sample table for users
id user_id
1 userA
2 userB
3 userC
4 userD
5 userE
This is the sample table for follows
id user_id follower_id
1 userA userB
2 userD userB
I like to return a result that includes this follower/following state. For example for userB (he follows A and D but not C and E:
id followedBy areWeFollowing
1 userA 1
2 userB 0
3 userC 0
4 userD 1
5 userE 0
Thanks for your help!
arda
you can even take a count also from second table for this situation -
select id,user_id, ( select count(*)
from follows
where follows.user_id = users.user_id
and follows.follower_id = 'userB') as areWeFollowing
from users