Laatste vijf artikelen ophalen uit alle categoriëen
Momenteel heb ik dit stukje oude code waarbij ik dus een query uitvoer met in het statement een extra query.
Resultaat: met 8 categorieën dus 9 queries. Dit wil ik dus -als het kán- omlaag brengen naar één query.
En zo een resultaat wil ik eruit halen, en de enter halverwege heb ik even voor het overzicht geplaatst.
Title - DateCreation - Category
-----------------------------
Bla die bla - 11-5-2022 - Categorie A
Bla die bla - 12-5-2022 - Categorie A
Bla die bla - 13-5-2022 - Categorie A
Bla die bla - 14-5-2022 - Categorie A
Bla die bla - 15-5-2022 - Categorie A
Bla die bla - 11-5-2022 - Categorie B
Bla die bla - 12-5-2022 - Categorie B
Bla die bla - 13-5-2022 - Categorie B
Bla die bla - 14-5-2022 - Categorie B
Bla die bla - 15-5-2022 - Categorie B
Dit stukje code heb ik momenteel, maar er moet toch een query mogelijk zijn om bovenstaand resultaat te krijgen, zodat ik die tweede whileloop kan laten vervallen?
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
<?php
$data = array();
$result_cats = $db->query("SELECT ID, Title, Keyword FROM news_categories");
while ($newscat = $result_cats->fetch_assoc()) {
$sql = "SELECT ID, Title, DateCreation, Author FROM news_articles WHERE catID ='" . $db->real_escape_string($newscat['ID']) . "' AND concept=0 ORDER BY DateCreation DESC LIMIT 5";
$result_items = $db->query($sql);
while ($item = $result_items->fetch_assoc()) {
$item['slug'] = $slug->create($item['Title']);
$data[$newscat['Title']][] = $item;
}
}
?>
$data = array();
$result_cats = $db->query("SELECT ID, Title, Keyword FROM news_categories");
while ($newscat = $result_cats->fetch_assoc()) {
$sql = "SELECT ID, Title, DateCreation, Author FROM news_articles WHERE catID ='" . $db->real_escape_string($newscat['ID']) . "' AND concept=0 ORDER BY DateCreation DESC LIMIT 5";
$result_items = $db->query($sql);
while ($item = $result_items->fetch_assoc()) {
$item['slug'] = $slug->create($item['Title']);
$data[$newscat['Title']][] = $item;
}
}
?>
Gewijzigd op 16/05/2022 00:47:23 door - Ariën -
https://stackoverflow.com/questions/1442527/how-to-select-the-newest-four-items-per-category
https://stackoverflow.com/questions/1313120/retrieving-the-last-record-in-each-group-mysql
Want wanneer je het met een HAVING doet, moet de database eerst alle rijen evalueren en dat pakt nadelig uit voor de performance.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
select `title`, cat, wanneer
from
(
select `title`, cat, `DateCreation`,
(@rn:=if(@prev = cat, @rn +1, 1)) as rownumb,
@prev:= cat
from
(
SELECT `title`, cat, `DateCreation`
FROM {table_name}
ORDER BY cat , `DateCreation` desc, `title`
) as sortedlist
JOIN (select @prev:=NULL, @rn :=0) as vars
ORDER BY cat, `DateCreation`
) as groupedlist
WHERE rownumb<=5
ORDER BY cat , `DateCreation` desc, `title`;
from
(
select `title`, cat, `DateCreation`,
(@rn:=if(@prev = cat, @rn +1, 1)) as rownumb,
@prev:= cat
from
(
SELECT `title`, cat, `DateCreation`
FROM {table_name}
ORDER BY cat , `DateCreation` desc, `title`
) as sortedlist
JOIN (select @prev:=NULL, @rn :=0) as vars
ORDER BY cat, `DateCreation`
) as groupedlist
WHERE rownumb<=5
ORDER BY cat , `DateCreation` desc, `title`;
Gewijzigd op 16/05/2022 14:05:26 door Spike Spade
https://www.sqlines.com/mysql/how-to/get_top_n_each_group
De SQL code (MariaDB 10) volgens het laatste voorbeeld :
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
SELECT
mk.brand AS brand,
models.model AS model
FROM (
SELECT
models.brand_id AS brand_id,
models.model AS model,
row_number() over ( partition by models.brand_id
ORDER BY
models.brand_id DESC ) AS mobiel_rank
FROM models ) ranked
LEFT JOIN
make mk
ON
mk.id = brand_id
WHERE
mobiel_rank <= 5 AND brand_id <= 20; # aanpassen naar behoefte
mk.brand AS brand,
models.model AS model
FROM (
SELECT
models.brand_id AS brand_id,
models.model AS model,
row_number() over ( partition by models.brand_id
ORDER BY
models.brand_id DESC ) AS mobiel_rank
FROM models ) ranked
LEFT JOIN
make mk
ON
mk.id = brand_id
WHERE
mobiel_rank <= 5 AND brand_id <= 20; # aanpassen naar behoefte
Je zou er een VIEW of een STORED PROCEDURE van kunnen maken.
De bijbehorende database :
https://github.com/VinceG/Auto-Cars-Makes-And-Models
Gewijzigd op 16/05/2022 16:23:04 door Adoptive Solution
Thanks voor de reacties. Ik ga er morgen even naar kijken en uitzoeken hoe dit werkt. ;-)
#4015 - Window function is allowed only in SELECT list and ORDER BY clause
Uiteindelijk kwam ik uit op iets als dit:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[mysql]
WITH testtabel AS (
SELECT 'a' AS categorie, 1 AS nummer
UNION SELECT 'a', 2
UNION SELECT 'a', 3
UNION SELECT 'b', 4
UNION SELECT 'b', 5
UNION SELECT 'b', 6
), gesorteerd AS (
SELECT testtabel.*,
ROW_NUMBER() OVER (
PARTITION BY categorie
ORDER BY nummer DESC
) AS rn
FROM testtabel
)
SELECT categorie, nummer
FROM gesorteerd
WHERE rn < 3;
[/mysql]
WITH testtabel AS (
SELECT 'a' AS categorie, 1 AS nummer
UNION SELECT 'a', 2
UNION SELECT 'a', 3
UNION SELECT 'b', 4
UNION SELECT 'b', 5
UNION SELECT 'b', 6
), gesorteerd AS (
SELECT testtabel.*,
ROW_NUMBER() OVER (
PARTITION BY categorie
ORDER BY nummer DESC
) AS rn
FROM testtabel
)
SELECT categorie, nummer
FROM gesorteerd
WHERE rn < 3;
[/mysql]
Teruglezend is dat dezelfde oplossing als wat Adoptive Solution schreef, maar dan met CTE in plaats van nested SELECTs. Dus die van Adoptive Solution is beter, omdat die ook met eerdere versies van MySQL werkt.
Het punt is wel dat ik een recente MariaDB gebruik. Ik ga ervanuit dat dit ook daarop zal werken gezien het een fork is.
Daarmee had ik het getest, het is wat er op mijn bijna verouderde Synology NAS staat, maak je geen zorgen.