how is this query done in mysql? - mysql

Given the following table ...
ID USER NUM
1 1 69
2 2 75
3 3 7
4 1 31
5 2 18
6 3 70
7 1 12
8 2 23
9 3 42
... which query would return rows with the lowest NUM for each USER?
The result should look like ...
ID USER NUM
7 1 12
5 2 18
3 3 7
Can't wrap my head around this one! Assuming it has a GROUP BY, but everything I try fails... Any pointers?

SELECT t.*
FROM tablename t
INNER JOIN (SELECT user, MIN(num) num
FROM tablename
GROUP BY user) x ON t.user = x.user AND t.num = x.num
or
SELECT t1.*
FROM tablename t1
LEFT JOIN tablename t2 ON t1.user = t2.user AND t1.num > t2.num
WHERE t2.id IS NULL

SELECT ID , MIN(NUM) as MIN_NUM , USER FROM usertable GROUP BY USER
Have a look at demo http://sqlfiddle.com/#!2/ce2fd/1

HEre is another method. UPDATED WITH THE CORRECT REREFERENCE
SQLFIDDLE
Query
select b.id, a.user, a.minnum from
mytable as b
join
(select user, min(num) as minnum
from mytable
group by user
) as a
on b.user = a.user
where b.num = a.minnum
order by a.minnum asc
limit 3
;
Results:
ID USER MINNUM
3 3 7
7 1 12
5 2 18

Related

I need help to find solution for this query in MySQL?

I have MySQL table as follow:
id p_id c_id
1 11 1
2 11 2
3 11 3
4 12 1
5 12 3
6 13 1
7 13 2
I need a query that when c_id is 1 and 2, it should return 11 and 13 of p_id.
I have tried the following query:
SELECT DISTINCT p_id FROM `Table Name` where c_id in (1,2)
which returns: 11, 12, 13.
but I only need it to return: 11 , 13.
You can write your query as:
SELECT DISTINCT a.p_id
FROM table_name AS a
JOIN table_name AS b ON a.p_id=b.p_id
WHERE a.c_id ='1' AND b.c_id ='2';
It's a self-join on the table itself
SELECT DISTINCT a.p_id
FROM table_name AS a
JOIN table_name AS b ON a.p_id=b.p_id
WHERE a.c_id ='1' AND b.c_id ='2';
it worked fo me
Your query is checking for p_ids related to c_is 1 or 2. But what you want is 1 and 2. You can write this like this:
SELECT DISTINCT t1.p_id
FROM table_name as t1
JOIN table_name as t2
ON t1.id = t2.id
WHERE t1.c_id = 1 AND t2.c_id = 2;
SELECT x.id
FROM my_table x
WHERE other_column IN('a','b')
GROUP
BY x.id
HAVING COUNT(*) = 2;

How to join same table to check if a>b with 10

Table mytable
id numbers whereonly
1 2 1
2 35 1
3 22 1
4 20 1
5 3 1
6 70 1
7 80.15925 1
8 60 7
9 50 7
I need to order by numbers and to take id 1 to search until I found an id that have numbers row bigger with 10.
Desired result: 2, 20, 35, 70, 80.15925
Only where column whereonly is 1
Is there a way to do this?
You can give this a try:
SELECT DISTINCT t1.id AS id, t1.numbers AS numbers
FROM table AS t1
INNER JOIN table AS t2 ON t1.numbers > t2.numbers - 10
WHERE t1.whereonly = 1
GROUP BY t2.numbers
ORDER BY t1.numbers;
Here is the sqlfiddle.
Edit 1: As strawberry suggested
SELECT DISTINCT x.*
FROM mytable x
JOIN
( SELECT t2.numbers t2n
, MIN(t1.id) id
FROM mytable t1
JOIN mytable t2
ON t1.numbers > t2.numbers - 10
GROUP
BY t2.numbers
) y
ON y.id = x.id
ORDER BY x.numbers
WHERE x.whereonly = 1;
Here is the sqlfiddle.

Column calculated by column with grouping

I have a simple table -
id | date | type | value
-------------------------
1 1/1/14 A 1
2 1/1/14 A 10
3 2/1/14 A 10
4 2/1/14 A 15
5 2/1/14 B 15
6 2/1/14 B 20
I would like to create a new column which calculates the minimum value per day per type. So giving the following results -
id | date | type | value | min_day
-----------------------------------
1 1/1/14 A 1 1
2 1/1/14 A 10 1
3 2/1/14 A 10 10
4 2/1/14 A 15 10
5 2/1/14 B 15 15
6 2/1/14 B 20 15
Is this possible? If so how would I go about it? I've been looking into triggers.
Thanks for any help.
First create a field named min_day in your table. Then you can use JOIN in an UPDATE query.
Try this:
UPDATE TableName T1 JOIN
(SELECT date,type,MIN(value) as MinValue
FROM TableName
GROUP BY type,date) T2 ON T1.type=T2.type AND T1.date=T2.date
SET T1.min_day = T2.MinValue
An example in SQL Fiddle.
EDIT:
For day-wise grouping:
UPDATE TableName T1 JOIN
(SELECT MONTH(date) as mon,type,MIN(value) as MinValue
FROM TableName
GROUP BY type,MONTH(date)) T2 ON T1.type=T2.type AND MONTH(T1.date)=T2.mon
SET T1.min_day = T2.MinValue
Result in SQL Fiddle.
Assuming that your table's name is mytable, try this:
SELECT mt.id,
mt.date,
mt.type,
mt.value,
mt.min_day,
md.min_value
FROM mytable mt
LEFT JOIN
(SELECT date, MIN(value) min_value FROM mytable GROUP BY DATE
) md
ON mt.date=md.date;
SELECT t1.*,
t2.min_day
FROM Table1 AS t1
JOIN
(SELECT date,TYPE,
min(value) AS min_day
FROM table1
GROUP BY date,TYPE) AS t2 ON t1.TYPE = t2.TYPE
AND t1.date = t2.date

Sum from different fields in different MySQL tables

I have these 2 tables:
table1
uid points
5 13
7 9
12 5
17 3
1 1
2 2
3 1
table2
uid points
9 21
13 17
15 11
17 7
12 6
2 2
1 3
22 1
I need a query to return top 5 users have points
Target result:
uid points
9 21
13 17
5 13
12 11
15 11
What I tried:
select uid, count(points) c from table1 order by c limit 5
union all
select uid, count(points) c from table2 order by c limit 5
But I did not get what I want.
SELECT al.uid as UID , SUM(al.points) AS total_points FROM (SELECT points, uid FROM table1
UNION ALL
SELECT points,uid FROM table2) al group by al.uid
Try This
select uid, (table1.points + table2.points) as c from table1
Left join table2 on table1.uid = table2.uid
order by (table1.points + table2.points) desc limit 5
You can try this query
Select
t3.uid , SUM(t3.points) As points
From
(SELECT * from Table1 UNION ALL SELECT * from Table2) t3
GROUP by
t3.uid
Order by
SUM(t3.points) DESC
LIMIT 5
demo at http://sqlfiddle.com/#!2/5605d/23
Try this:
SELECT Uid,SUM(Points)
FROM
(
SELECT Uid,Points FROM Table1
UNION ALL
SELECT Uid,Points FROM Table2
) as T
GROUP BY Uid
ORDER BY SUM(Points) DESC
LIMIT 5
SQLFiddle demo
If you want the top 5 overall, you need to use an order by and limit over a subquery:
select uid, sum(points) points from (
select uid, points from table1
union all
select uid, points from table2
) x
group by uid
order by sum(points) desc
limit 5

Selecting record from two tables with INNER join limit 3

I have records in two tables as shown below
Table1
userid email
1 123#qwe.com
4 qwe#sdf.cok
5 sad#fgdf.sdf
7 dsvh#dsf.we
9 fdsdf#fgh.hh
.
Table 2
userid values
1 15
1 45
1 76
1 15345
4 4545
4 76788
4 15879
5 4534
5 76345
5 15678
5 4567
5 7667789
7 15
7 456786
7 76678
7 15678
9 45789
9 76789
9 15789
9 4557
9 7667
9 1556
9 4556
9 764
Now I want the first 3 records from table1 with userid in descending order along with the table2 records related to them
SELECT *
FROM (SELECT TOP 3 * FROM Table1) AS Table1 INNER JOIN
Table2 ON Table1.userid = Table2.userid
ORDER BY Table1.userid
SELECT a.userid, a.email, b.values
FROM table1 a
INNER JOIN table2 b ON a.userid = b.userid
ORDER BY a.userid asc
LIMIT 0,3
SELECT * FROM (
SELECT t1.userid, t1.email, group_concat(t2.`values`) as t2values
FROM table1 t1
INNER JOIN table2 t2 ON (t1.userid = t2.userid)
GROUP BY t1.userid
ORDER BY t1.userid ASC
LIMIT 3 ) subselect
ORDER BY subselect.userid DESC
Explanation:
Group_concat is an aggregate function that will make a list of comma separated values.
Because you are using an aggregate function you need to group on userid.
The limit 3 selects the first 3 userid's (because you've ordered ASC)
Then the outer select picks up all 3 rows and reverses the order to DESC.
Links
http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat