MySQL : Select three last item INNER JOIN [duplicate] - mysql

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

MySQL select users who was in range of dates

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.

Mysql Row To Column Select Specific Data

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

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?

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

Concatenate string with the number of ocurrence

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