This question already has answers here:
Using LIMIT within GROUP BY to get N results per group?
(14 answers)
Closed 7 years ago.
Just have a tricky blockING with MySQL.
I've 3 tables :
TV
| TV_ID | TV_name |
----------------------
| 1 | HBO |
| 2 | BBC |
| 3 | Fox news |
----------------------
----------------------
----------------------
Emission
| E_ID | E_TV_ID | E_NAME |
-------------------------------
| 1 | 1 | Weather |
| 2 | 1 | News |
| 3 | 1 | FAKE1 |
| 4 | 1 | FAKE2 |
| 5 | 1 | FAKE3 |
| 6 | 1 | FAKE4 |
| 7 | 2 | FAKE5 |
| 8 | 2 | FAKE6 |
| 9 | 2 | FAKE7 |
| 10 | 2 | FAKE8 |
| 11 | 2 | FAKE9 |
| 12 | 2 | FAKE10 |
| 13 | 2 | FAKE11 |
| 14 | 3 | FAKE12 |
| 15 | 3 | FAKE13 |
| 16 | 3 | FAKE14 |
| 17 | 3 | FAKE15 |
| 18 | 3 | FAKE16 |
| 19 | 3 | FAKE17 |
| 20 | 3 | FAKE18 |
-------------------------------
-------------------------------
-------------------------------
Replay
| R_ID | R_E_ID | R_DATE | R_URL_REPLAY |
-------------------------------------------
| 1 | 1 | 20150431 | URL1 |
| 2 | 20 | 20150431 | URL2 |
| 3 | 19 | 20150431 | URL3 |
| 4 | 2 | 20150431 | URL4 |
| 5 | 7 | 20150431 | URL5 |
| 6 | 16 | 20150430 | URL6 |
| 7 | 10 | 20150430 | URL7 |
| 8 | 1 | 20150430 | URL8 |
| 9 | 4 | 20150430 | URL9 |
| 10 | 9 | 20150430 | URL10 |
| 11 | 19 | 20150429 | URL11 |
| 12 | 2 | 20150429 | URL12 |
| 13 | 1 | 20150429 | URL13 |
| 14 | 12 | 20150429 | URL14 |
-------------------------------------------
-------------------------------------------
-------------------------------------------
And I want to create ONLY ONE query to get 3rd last emission of each TV, order by date and TV (if possible).
So for this exemple, I've 3 TV. 3*3 = 9 emissions, like :
| TV_ID | E_NAME | R_URL_REPLAY |
-------------------------------------
| 1 | Weather | URL1 |
| 1 | FAKE2 | URL4 |
| 1 | FAKE6 | URL8 |
| 2 | FAKE3 | URL5 |
| 2 | FAKE8 | URL7 |
| 2 | FAKE7 | URL10 |
| 3 | FAKE18 | URL2 |
| 3 | FAKE17 | URL3 |
| 3 | FAKE14 | URL6 |
I've try many solution (INNER JOIN -- SELECT .. FROM ( SELECT ...) -- Use var #:= -- Sub-sub-sub-sub query ) but not works..
Only works if I use UNION, but I've more than 20 TV, and write 20 UNION is really urgly..
If you have suggestion,
Thanks in advance,
It's not straightforward, but in a nutshell, sort your replays by tv and date, then rank them, then select those that match your rank criteria.
select *
from (
select if(#prev = e_tv_id, #rank := #rank +1, #rank := 1 and #prev := e_tv_id) as rank, q.*
from (
select e.e_tv_id, r_date, r_url_replay
from emission e
join (select #prev := 0, #rank := 1) q
inner join replay r
on r.r_e_id = e.e_id
order by e.e_tv_id asc, r.r_date desc
) q
) qq
where rank <=3 ;
demo here
Related
Hello :) I need to create sql which will calculate advances for user but only for that one who was in work. Tables looks like:
users:
| id | firstName | lastName |
| -- | --------- | -------- |
| 1 | John 1 | Test 1 |
| 2 | John 2 | Test 2 |
| 3 | John 3 | Test 3 |
| 4 | John 4 | Test 4 |
users_advances:
| id | user_id | amount | d_add | status_id |
| -- | ------- | ------ | ---------- | --------- |
| 1 | 1 | 100 | 2022-07-09 | 1 |
| 2 | 1 | 50 | 2022-07-10 | 2 |
| 3 | 2 | 100 | 2022-07-03 | 1 |
| 4 | 2 | 50 | 2022-07-05 | 2 |
| 5 | 2 | 100 | 2022-03-09 | 1 |
| 6 | 1 | 50 | 2022-07-02 | 2 |
users_arrivals
| id | user_id | start_date | end_date |
| -- | ------- | ---------- | ---------- |
| 1 | 1 | 2022-09-01 | 2022-09-30 |
| 2 | 2 | 2022-09-22 | 2022-09-25 |
| 3 | 3 | 2022-09-19 | 2022-09-25 |
I created SQL
SELECT u.id AS user_id, CONCAT(u.firstName, SPACE(1), u.lastName) AS fullName, IFNULL(SUM(uz.amount), 0) AS suma
FROM users u
LEFT JOIN users_advances uz ON uz.user_id = u.id AND (uz.d_add BETWEEN '2022-09-19' AND '2022-09-25') AND ((uz.status_id = 1) OR (uz.status_id = 2))
LEFT JOIN users_arrivals po ON po.user_id = u.id
WHERE po.start_date <= '2022-09-19' AND po.end_date >= '2022-09-24'
GROUP BY u.id
but it doesnt return me user 2 who had start_date at 2022-09-22.
I have column user and rating.
SELECT rating.idUser, user.nmUser, rating.idBengkel, rating.nilai FROM `rating`
JOIN user on rating.idUser = user.idUser
WHERE rating.idBengkel=1 or rating.idBengkel=2
Result :
+--------+---------------------------+-----------+-------+
| idUser | nmUser | idBengkel | nilai |
+--------+---------------------------+-----------+-------+
| 10 | Hudson mas77 | 1 | 5 |
| 11 | Vina Nurfadzilah | 1 | 5 |
| 12 | Angelica Amartya | 1 | 5 |
| 15 | Syahrul K | 1 | 4 |
| 27 | Ashar Murdihastomo | 1 | 5 |
| 28 | Eril Obeit Choiri | 1 | 2 |
| 29 | Ariyadi | 1 | 3 |
| 30 | Robertus Dwian Augusta | 1 | 4 |
| 31 | Irfan Setiaji | 1 | 4 |
| 33 | Baby Ayuna | 1 | 5 |
| 9 | Nur k hamid | 2 | 5 |
| 10 | Hudson mas77 | 2 | 5 |
| 13 | Yuana Putra | 2 | 4 |
| 14 | Nanda Aulia Irza Ramadhan | 2 | 4 |
| 26 | taufiq rahman | 2 | 5 |
| 27 | Ashar Murdihastomo | 2 | 5 |
| 28 | Eril Obeit Choiri | 2 | 5 |
| 30 | Robertus Dwian Augusta | 2 | 4 |
| 44 | halim budiono | 2 | 1 |
+--------+---------------------------+-----------+-------+
When i try to get similar records using this query
SELECT rating.idUser, user.nmUser FROM rating
JOIN user
ON rating.idUser = user.idUser
WHERE rating.idBengkel = 1 and rating.idUser
IN (SELECT rating.idUser from rating WHERE rating.idBengkel = 2)
ORDER by idUser
Result :
+-----------+------------------------+
| idUser | nmUser |
+-----------+------------------------+
| 10 | Hudson mas77 |
| 27 | Ashar Murdihastomo |
| 28 | Eril Obeit Choiri |
| 30 | Robertus Dwian Augusta |
+-----------+------------------------+
The result work fine, but I want show column 'nilai' as ItemX and ItemY. Those are user similar data. In this case I have 4 similar user who rate on idBengkel=1 and idBengkel=2 as the results above. I want it like the table below.
+--------+------------------------+-------+-------+
| idUser | nmUser | ItemX | ItemY |
+--------+------------------------+-------+-------+
| 10 | Hudson mas77 | 5 | 5 |
| 27 | Ashar Murdihastomo | 5 | 5 |
| 28 | Eril Obeit Choiri | 2 | 5 |
| 30 | Robertus Dwian Augusta | 4 | 4 |
+--------+------------------------+-------+-------+
I need solution for this and i was trying with this solution in https://stackoverflow.com/a/7976379/12396302 but it resulting more than one row. Please help me, I cant implement that query's solution. Regards!
I think you need below query -
SELECT rating.idUser,
user.nmUser,
MAX(CASE WHEN rating.idBengkel = 1 THEN rating.nilai END) ItemX,
MAX(CASE WHEN rating.idBengkel = 2 THEN rating.nilai END) ItemY,
FROM `rating`
JOIN user on rating.idUser = user.idUser
WHERE rating.idBengkel IN (1, 2)
GROUP BY rating.idUser,
user.nmUser
I want to ranking result with city based in mysql
table1:-users
| user_id | marks |
--------------------
| 1 | 10 |
| 5 | 10 |
| 5 | 50 |
| 3 | 15 |
| 4 | 10 |
| 2 | 10 |
| 6 | 10 |
| 6 | 50 |
| 4 | 15 |
| 4 | 10 |
table:-2 users details
| user_id | city |
--------------------
| 1 | newdelhi |
| 2 | kolkata |
| 3 | mumbai |
| 4 | newdelhi |
| 5
| 6 | newdelhi |
I want to result like this:
| user_id | points |
--------------------
| 6 | 60 |
| 4 | 35 |
| 1 | 10 |
Try this :
SELECT
users.user_id
,SUM(users.marks) AS points
FROM
users
INNER JOIN
users_details ON users.user_id = users_details.user_id
WHERE
users_details.city = 'newdelhi'
GROUP BY
user_id
How to get count of combinations from database?
I have to database tables and want to get the count of combinations. Does anybody know how to put this in a database query, therefore I haven't a db request for each trip?
Trips
| ID | Driver | Date |
|----|--------|------------|
| 1 | A | 2015-12-15 |
| 2 | A | 2015-12-16 |
| 3 | B | 2015-12-17 |
| 4 | A | 2015-12-18 |
| 5 | A | 2015-12-19 |
Passengers
| ID | PassengerID | TripID |
|----|-------------|--------|
| 1 | B | 1 |
| 2 | C | 1 |
| 3 | D | 1 |
| 4 | B | 2 |
| 5 | D | 2 |
| 6 | A | 3 |
| 7 | B | 4 |
| 8 | D | 4 |
| 9 | B | 5 |
| 10 | C | 5 |
Expected result
| Driver | B-C-D | B-D | A | B-C |
|--------|-------|-----|---|-----|
| A | 1 | 2 | - | 1 |
| B | - | - | 1 | - |
Alternative
| Driver | Passengers | Count |
|--------|------------|-------|
| A | B-C-D | 1 |
| A | B-D | 2 |
| A | B-C | 1 |
| B | A | 1 |
Has anybody an idea?
Thanks a lot!
Try this:
SELECT Driver, Passengers, COUNT(*) AS `Count`
FROM (
SELECT t.ID, t.Driver,
GROUP_CONCAT(p.PassengerID
ORDER BY p.PassengerID
SEPARATOR '-') AS Passengers
FROM Trips AS t
INNER JOIN Passengers AS p ON t.ID = p.TripID
GROUP BY t.ID, t.Driver) AS t
GROUP BY Driver, Passengers
The above query will produce the alternative result set. The other result set can only be achieved using dynamic sql.
Demo here
I'm migrating a database from one application to another. In the first one I've two tables: proyectos and presupuestos. A row in 'proyectos' can have one or more rows in 'presupuestos'.
The new application has a field in presupuestos that is made concatenating the code of the proyect with the number of 'presupuesto' of this proyect. That's what I don't know how to do it.
My tables are like:
Proyectos:
+--------------+------------------+
| proyectos_id | proyectos_codigo |
+--------------+------------------+
| 1 | E+-00001 |
| 2 | E+-00002 |
| 3 | E+-00003 |
| 4 | E+-00004 |
| 5 | E+-00005 |
+--------------+------------------+
Presupuestos:
+-----------------+--------------+
| presupuestos_id | proyectos_id |
+-----------------+--------------+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 3 |
| 6 | 3 |
| 7 | 3 |
| 8 | 4 |
| 9 | 4 |
| 10 | 5 |
+-----------------+--------------+
I've tried with this query:
select presupuestos_id, p.proyectos_id, concat(pr.proyectos_codigo,'_1') from presupuestos p join proyectos pr on p.proyectos_id = pr.proyectos_id
Which result is:
+-----------------+--------------+----------------------------------+
| presupuestos_id | proyectos_id | concat(pr.proyectos_codigo,'_1') |
+-----------------+--------------+----------------------------------+
| 1 | 1 | E+-00001_1 |
| 2 | 1 | E+-00001_1 |
| 3 | 1 | E+-00001_1 |
| 4 | 2 | E+-00002_1 |
| 5 | 3 | E+-00003_1 |
| 6 | 3 | E+-00003_1 |
| 7 | 3 | E+-00003_1 |
| 8 | 4 | E+-00004_1 |
| 9 | 4 | E+-00004_1 |
| 10 | 5 | E+-00005_1 |
+-----------------+--------------+----------------------------------+
But obviusly, It doesn't what I want. My desired result is:
+-----------------+--------------+----------------------------------+
| presupuestos_id | proyectos_id | some code |
+-----------------+--------------+----------------------------------+
| 1 | 1 | E+-00001_1 |
| 2 | 1 | E+-00001_2 |
| 3 | 1 | E+-00001_3 |
| 4 | 2 | E+-00002_1 |
| 5 | 3 | E+-00003_1 |
| 6 | 3 | E+-00003_2 |
| 7 | 3 | E+-00003_3 |
| 8 | 4 | E+-00004_1 |
| 9 | 4 | E+-00004_2 |
| 10 | 5 | E+-00005_1 |
+-----------------+--------------+----------------------------------+
Try this :
SELECT presupuestos_id, p.proyectos_id,
CONCAT(pr.proyectos_codigo,'_',
(CASE p.proyectos_id
WHEN #p_id
THEN #rownumber := #rownumber + 1
ELSE #rownumber := 1 AND #p_id := p.proyectos_id END)
)AS result
FROM presupuestos p
JOIN proyectos pr ON p.proyectos_id = pr.proyectos_id
JOIN (SELECT #rownumber:=0, #p_id:='') AS t
This should do what you want, although the answer by RubahMalam looks better... :
SELECT a.presupuestos_id, a.proyectos_id, concat(p.proyectos_codigo,'_', count(*)) as "Some code"
FROM (
SELECT pr.presupuestos_id, pr.proyectos_id
FROM Presupuestos pr JOIN Proyectos p ON pr.proyectos_id = p.proyectos_id
) a
JOIN (
SELECT pr.presupuestos_id, pr.proyectos_id
FROM Presupuestos pr JOIN Proyectos p ON pr.proyectos_id = p.proyectos_id
) b
ON a.proyectos_id = b.proyectos_id AND a.presupuestos_id >= b.presupuestos_id
JOIN Proyectos p ON a.proyectos_id = p.proyectos_id
GROUP BY a.proyectos_id, a.presupuestos_id, p.proyectos_codigo
Sample SQL Fiddle