"Looping" the same SQL query for all entries grouped by date - mysql

I have a table like this:
+------------+-----------+------+----+
| date | player_id | rank | hp |
+------------+-----------+------+----+
| 2021-01-01 | 1 | 1 | 39 |
| 2021-01-01 | 5 | 2 | 20 |
| 2021-01-01 | 2 | 3 | 12 |
| 2021-01-01 | 3 | 4 | 48 |
| 2021-01-01 | 4 | 5 | 25 |
| 2021-01-02 | 1 | 2 | 42 |
| 2021-01-02 | 2 | 1 | 38 |
| 2021-01-02 | 3 | 4 | 21 |
| 2021-01-02 | 4 | 3 | 35 |
| 2021-01-02 | 5 | 5 | 28 |
| 2021-01-03 | 1 | 5 | 38 |
| 2021-01-03 | 3 | 2 | 31 |
| 2021-01-03 | 2 | 3 | 26 |
| 2021-01-03 | 4 | 4 | 22 |
| 2021-01-03 | 5 | 1 | 19 |
+------------+-----------+------+----+
When I use the following SQL code:
SELECT * FROM
(SELECT * FROM `players` WHERE date='2021-01-01' ORDER BY rank ASC LIMIT 3) highest_rank
ORDER BY hp DESC LIMIT 2
The result will be this:
+------------+-----------+------+----+
| date | player_id | rank | hp |
+------------+-----------+------+----+
| 2021-01-01 | 1 | 1 | 39 |
| 2021-01-01 | 5 | 2 | 20 |
+------------+-----------+------+----+
My problem is the result is only for date='2021-01-01'. I want to do this for every day in the database. Ultimately, I want the result to look like this:
+------------+-----------+------+----+
| date | player_id | rank | hp |
+------------+-----------+------+----+
| 2021-01-01 | 1 | 1 | 39 |
| 2021-01-01 | 5 | 2 | 20 |
| 2021-01-02 | 1 | 2 | 42 |
| 2021-01-02 | 2 | 1 | 38 |
| 2021-01-03 | 3 | 2 | 31 |
| 2021-01-03 | 2 | 3 | 26 |
+------------+-----------+------+----+
How can this be done? I'm using MySQL/MariaDB if that makes any difference.

Problem solved. Credit goes to sticky bit in the comment section that provided a solution that almost worked. He retracted the suggestion because it wasn't the final solution, I think. But I tinkered with it and got it to work. Thank you, sticky bit!
For anyone interested in the solution:
SELECT date, player_id, rank, hp
FROM
(
SELECT *,
row_number() OVER (PARTITION BY date
ORDER BY hp DESC) h
FROM
(
SELECT *,
row_number() OVER (PARTITION BY date
ORDER BY rank ASC) r
FROM players
) x
WHERE r<=3
) y
WHERE h<=2

Related

sql joins with multiple conditions

i have two tables, (say bill and soldproduct)
select * from bill;
+------+------------+------------+
| id | solddate | customerId |
+------+------------+------------+
| 11 | 2018-07-23 | 1 |
| 12 | 2018-07-21 | 1 |
| 13 | 2018-08-02 | 2 |
| 14 | 2018-08-08 | 2 |
| 15 | 2018-08-08 | 1 |
| 16 | 2018-08-08 | 1 |
+------+------------+------------+
select * from soldproduct;
+--------+-------------+----------+-------+------------+
| billid | productname | quantity | price | totalprice |
+--------+-------------+----------+-------+------------+
| 11 | book | 2 | 100 | 200 |
| 11 | pen | 10 | 10 | 100 |
| 11 | pencil | 5 | 2 | 10 |
| 12 | pencil | 5 | 2 | 10 |
| 13 | pen | 10 | 10 | 100 |
| 13 | book | 2 | 100 | 200 |
| 14 | pen | 1 | 10 | 10 |
| 14 | bottle | 1 | 75 | 75 |
| 15 | phone | 1 | 5000 | 5000 |
| 16 | lock | 15 | 50 | 750 |
+--------+-------------+----------+-------+------------+
I need to find the highest bill id using totalprice.
I tried using
select billid,sum(totalprice)
from soldproduct
where billid in (select id from bill where solddate >= date_sub(curdate(),interval 1 month))
group by billid
order by totalprice desc;
and my output is
+--------+-----------------+
| billid | sum(totalprice) |
+--------+-----------------+
| 15 | 5000 |
| 16 | 750 |
| 11 | 310 |
| 13 | 300 |
| 12 | 10 |
| 14 | 85 |
+--------+-----------------+
How do i get the same output with a single query using joins (without using subquery)?
try the following join
select billid,sum(totalprice)
from soldproduct
join bill on soldproduct.billid = bill.id and solddate >= date_sub(curdate(),interval 1
month)
group by billid
order by totalprice desc;
Can you try the below query:(I do not tested it out)
SELECT billid, SUM(totalprice)
FROM soldproduct SP
JOIN bill B ON (B.id = SP.billid)
WHERE B.solddate BETWEEN (CURRENT_DATE() - INTERVAL 1 MONTH) AND CURRENT_DATE()
GROUP BY SP.billid
ORDER BY SP.totalprice DESC;

MySQL: Get everyday incremental data

I want to fetch the data from Table based on date but in an incremental way.
Suppose I have data like this which is grouped by date
| DATE | Count |
| 2015-06-23 | 10 |
| 2015-06-24 | 8 |
| 2015-06-25 | 6 |
| 2015-06-26 | 3 |
| 2015-06-27 | 2 |
| 2015-06-29 | 2 |
| 2015-06-30 | 3 |
| 2015-07-01 | 1 |
| 2015-07-02 | 3 |
| 2015-07-03 | 4 |
So the result should come like this
| DATE | Count| Sum|
| 2015-06-23 | 10 | 10 |
| 2015-06-24 | 8 | 18 |
| 2015-06-25 | 6 | 24 |
| 2015-06-26 | 3 | 27 |
| 2015-06-27 | 2 | 29 |
| 2015-06-29 | 2 | 31 |
| 2015-06-30 | 3 | 34 |
| 2015-07-01 | 1 | 35 |
| 2015-07-02 | 3 | 38 |
| 2015-07-03 | 4 | 42 |
You would join every other previous date on that date, and then sum the count on that
If you give me your table structure, I can make it run.
id, name, date_joined
SELECT counts.theCount, sum(counts.theCount), table.date_joined
FROM yourTable
LEFT JOIN
(SELECT count(*) as theCount, table.date_joined
FROM yourTable
GROUP BY table.date_joined
) as counts
ON
yourTable.date_joined> counts.date_joined
GROUP BY yourTable.date_joined

MySQL query to meet specific needs

My table is as follow:
-------------------------------------------
| rec_id | A_id | B_id |Date(YYYY-MM-DD)|
-------------------------------------------
| 1 | 1 | 6 | 2014-01-01 |
| 2 | 5 | 1 | 2014-01-02 |
| 3 | 2 | 6 | 2015-01-03 |
| 4 | 6 | 1 | 2014-01-04 |
| 5 | 7 | 1 | 2014-01-05 |
| 6 | 3 | 6 | 2014-01-06 |
| 7 | 8 | 1 | 2014-01-07 |
| 8 | 4 | 6 | 2014-01-08 |
| 9 | 9 | 1 | 2014-01-09 |
| 10 | 10 | 21 | 2014-01-10 |
| 11 | 12 | 21 | 2014-01-11 |
| 12 | 11 | 2 | 2014-01-12 |
| 13 | 1 | 1 | 2014-12-31 |
| 14 | 2 | 2 | 2014-12-31 |
| 15 | 1 | 1 | 2015-01-31 |
| 16 | 10 | 21 | 2015-01-31 |
| 17 | 1 | 21 | 2014-10-31 |
This table represents the possession of various "A_id" to a specific "B_id" with a date when it is possessed. The possession of each "A_id" can be changed later on at any time. That means the only the latest possession is considered.
I want to find out all the "A_id" that are currently (possessed in latest date) in possession of a specific "B_id". For example, for "B_id" = 6 the possessed "A_id" at present are as follows:
---------------------------
| A_id | Date(YYYY-MM-DD) |
---------------------------
| 2 | 2015-01-03 |
| 3 | 2014-01-06 |
| 4 | 2014-01-08 |
Similarly, for "B_id" = 21 the possessed "A_id" at present are as follows:
---------------------------
| A_id | Date(YYYY-MM-DD) |
---------------------------
| 10 | 2015-01-31 |
| 12 | 2014-01-11 |
I would highly appreciate your kind help in this regard.
One way to accomplish this is to use a correlated not exists predicate that makes sure that there doesn't exists any later possession for each A_ID with another B_ID.
SELECT A_ID, MAX(PDATE) AS DATE
FROM YOUR_TABLE T
WHERE B_ID = 6
AND NOT EXISTS (
SELECT 1
FROM YOUR_TABLE
WHERE A_ID = T.A_ID
AND PDATE > T.PDATE
AND B_ID <> T.B_ID
)
GROUP BY A_ID

MySQL query date ranges

I have googled but did not find anything related. I have a MySQL table like this:
+++++++++++++++++++++++++++++++
| roomID | date | price |
+++++++++++++++++++++++++++++++
| 1 | 2012-10-10 | 10 |
| 1 | 2012-10-11 | 10 |
| 1 | 2012-10-12 | 10 |
| 1 | 2012-10-13 | 12 |
| 2 | 2012-10-10 | 15 |
| 2 | 2012-10-11 | 15 |
| 2 | 2012-10-12 | 15 |
| 2 | 2012-10-13 | 16 |
| 2 | 2012-10-14 | 16 |
| 2 | 2012-10-15 | 16 |
+++++++++++++++++++++++++++++++
I need to get periods based on price and roomID:
++++++++++++++++++++++++++++++++++++++++++++
| roomID | from | till | price |
++++++++++++++++++++++++++++++++++++++++++++
| 1 | 2012-10-10 | 2012-10-12 | 10 |
| 1 | 2012-10-13 | 2012-10-13 | 12 |
| 2 | 2012-10-10 | 2012-10-12 | 15 |
| 2 | 2012-10-13 | 2012-10-15 | 16 |
++++++++++++++++++++++++++++++++++++++++++++
Thank you!
select roomid,
min(date) as from,
max(date) as till,
price
from periods
group by price
order by price
You can try using the following query:
SELECT roomid, MIN(date) AS `from`, MAX(date) AS `till`, price
FROM tableName
GROUP BY price
ORDER BY price

join with a group by?

i have a table called rc_language_type_table with:
id language
1 english
2 Xhosa
3 afrikaans
etc
then i have a table rc_language_type_assoc_table with:
profile_id | language_type_id |
+------------+------------------+
| 3 | 1 |
| 13 | 1 |
| 15 | 1 |
| 16 | 1 |
where i have profiles and each profile is connected to a language id in a 1 to many
so then i did:
select *,count(*) from rc_language_type_assoc_table group by language_type_id;
+------------+------------------+----------+
| profile_id | language_type_id | count(*) |
+------------+------------------+----------+
| 3 | 1 | 96 |
| 3 | 2 | 19 |
| 3 | 3 | 18 |
| 64 | 4 | 51 |
| 94 | 5 | 10 |
| 37 | 6 | 26 |
| 3 | 7 | 21 |
| 3 | 8 | 4 |
| 3 | 9 | 6 |
| 88 | 10 | 4 |
| 3 | 11 | 3 |
+------------+------------------+----------+
what i want now is: instead having the language_type_id i want to display the actual language...how would i do this please???
i tried:
select *, count(*)
from rc_language_type_assoc_table, rc_language_type_table
group by language_type_id
where rc_language_type_assoc_table.language_type_id = rc_language_type_table.id;
but i get a syntax error...
please help??
thank you
GROUP BY should be "after" the WHERE statement and not before
select *, count(*)
from rc_language_type_assoc_table, rc_language_type_table
where rc_language_type_assoc_table.language_type_id = rc_language_type_table.id
group by language_type_id ;