I'm trying to create an sql (mariadb) request that select multiples columns but need two columns to be a unique pair but making sure the pair selected has its created_at value the least than the other duplicata pairs.
Here is what my table approximately looks like :
id
from_user_id
to_user_id
created_at
1
1
2
1000000005
2
2
1
1000000002
3
2
3
1000000008
4
5
6
999999999
5
6
5
100000006
I made this table precise to explain the request I want.
So I want to select the distinct pair (from_user_id, to_user_id) implying that the couple (1,2) which could also be (2,1) should be unique. The second rule is it should pick the couple with the minimum created_at value.
So the result table I want is :
id
from_user_id
to_user_id
created_at
2
2
1
1000000002
3
2
3
1000000008
4
5
6
999999999
2,1,1000000002 because the created_at is lesser than the other same couple case (1,2,1000000005).
In this case if I want only the values above created_at:999999999 to be selected I just have to add one condition.
I really hope my question is clear. I'm struggling to make distinct pairs work with other columns.
Thanks in advance for your answers.
WITH
cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY GREATEST(from_user_id,to_user_id),
LEAST(from_user_id,to_user_id)
ORDER BY created_at) rn
FROM table
)
SELECT *
FROM cte
WHERE rn = 1
Related
I need to assign jobs to users based on a score (number of "chances") calculated from previous jobs they have done. Here's my table of users:
user chances
Anna 6
Barry 4
Steve 3
Jackson 3
Helga 3
Maureen 3
Paul 3
Karen 2
Anita 2
Samson 2
Frank 2
Jean 1
Lilly 1
Boris 1
In another table, I have 100 rows of unassigned jobs (with currently NULL user), e.g.
id title user
1 Sort filing NULL
2 Clean office NULL
3 Order stationery NULL
I want to assign these jobs to the users above using a weighting based on the number of "chances" they have. For example, Anna will have 6 chances to be assigned one of these jobs, while Boris will have 1.
I've been playing around with a CASE which will assign a user to jobs, but nothing is satisfactory.
What's the best way for me to achieve this? Thanks
Presumably, you're after something like this...
SELECT user
FROM my_table
ORDER BY RAND() * chances * (SELECT SUM(chances) FROM my_table) DESC ;
If the changes are a small number and integers, then the easiest way might be:
update anothertable at
set user = (select user
from chances c cross join
(select 1 as n union all select 2 union all select 3 union all
select 4 union all select 5 union all select 6
) n
on c.chances <= n.n
where at.user is null
order by rand()
limit 1
);
The where clause is just so MySQL doesn't get the (brilliant) idea of optimizing away the subquery and only calling it once.
I have a table called "UserPlay" which as values like this
th_id route_id
1 1
1 2
1 2
1 3
1 3
I just want least time rout_id is used
I have to get output as this
th_id route
1 1
If I understand correctly, you want the route_id with the lowest count:
select route_id, count(*)
from UserPlay u
group by route_id
order by count(*) asc
limit 1;
You can get the list of the_id on it by including group_concat(the_id).
I am aggregating data and I cannot sum certain columns so I would like to take the most frequent observation from that column, or the mode value. Each ID can have only one site and number, so if there are ties then pick the smaller of the two numbers.
Example follows:
ID site number
1 3 45
1 3 45
1 2 56
1 3 56
2 4 5
2 5 5
2 5 3
2 5 5
I want it to look like:
ID site number
1 3 45
2 5 5
Here's one way of doing it:
with aggregation as
(
select id
, site
, number
, numberCount = count(1)
from SiteNumbers
group by id
, site
, number
), aggregateRanks as
(
select *
, idRank = row_number() over (partition by id order by numberCount desc, number, site)
from aggregation
)
select id
, site
, number
from aggregateRanks
where idRank = 1
SQL Fiddle with demo.
It matches your results, but depending on all your different cases might need some tweaking; hopefully it gives you some ideas.
I have a table of data like this:
id user_id A B C
=====================
1 15 1 2 3
2 15 1 2 5
3 20 1 3 9
4 20 1 3 7
I need to remove duplicate user ids and keep the record that sorts lowest when sorting by A then B then C. So using the above table, I set up a temp query (qry_temp) that simply does the sort--first on user_id, then on A, then on B, then on C. It returns the following:
id user_id A B C
====================
1 15 1 2 3
2 15 1 2 5
4 20 1 3 7
3 20 1 3 9
Then I wrote a Totals Query based on qry_temp that just had user_id (Group By) and then id (First), and I assumed this would return the following:
user_id id
===========
15 1
20 4
But it doesn't seem to do that--instead it appears to be just returning the lowest id in a group of duplicate user ids (so I get 1 and 3 instead of 1 and 4). Shouldn't the Totals query use the order of the query it's based upon? Is there a property setting in the query that might impact this or another way to get what I need? If it helps, here is the SQL:
SELECT qry_temp.user_id, First(qry_temp.ID) AS FirstOfID
FROM qry_temp
GROUP BY qry_temp.user_id;
You need a different type of query, for example:
SELECT tmp.id,
tmp.user_id,
tmp.a,
tmp.b,
tmp.c
FROM tmp
WHERE (( ( tmp.id ) IN (SELECT TOP 1 id
FROM tmp t
WHERE t.user_id = tmp.user_id
ORDER BY t.a,
t.b,
t.c,
t.id) ));
Where tmp is the name of your table. First, Last, Min and Max are not dependent on a sort order. In relational databases, sort orders are quite ephemeral.
I have a table hotel [hotelid,hotelname,etc]
and another table facilities[facilityid,facilityname]
these 2 tables are linked through table hotel_to_facilities_map[hotelid,facility_id]
so the table hotel_to_facilities_map might contain values as
hotelid facility_id
-------------------
1 3
1 5
1 6
2 6
2 2
2 5
now i want to retrieve all the hotels which match ALL facilities asked for
select * from hotel_to_facilities_map where facility_id IN (3,5,2)
but this will cause the match as an OR Expression while i need AND.
is there any workaround or solution for this?
select hotelid
from hotel_to_facilities_map
where facility_id in (3,5,2)
group by hotelid
having count(*) = 3