Opcją byłoby zapytanie, które współpracuje ze zmiennymi użytkownika w celu wygenerowania rankingu na podstawie daty.I wybierz tylko trzy ostatnie daty.
Zapytanie
SELECT
*
FROM (
SELECT
*
, CASE
WHEN @supplier = supplier
THEN @rank := @rank + 1
ELSE @rank := 1
END
AS rank
, @supplier := supplier
FROM
Expenses
CROSS JOIN (
SELECT
@supplier := NULL
, @rank := 0
)
AS
init_user_params
WHERE
product_id = 1
ORDER BY
supplier ASC
, DATE DESC
)
AS Expenses_ranked
WHERE
Expenses_ranked.rank <= 3
Wynik
id product_id cost quantity supplier date @supplier := NULL @rank := 0 rank @supplier := supplier
------ ---------- ------ -------- -------- ---------- ----------------- ---------- ------ -----------------------
4 1 3.98 2 1 2017-09-22 (NULL) 0 1 1
3 1 2.50 1 1 2017-09-20 (NULL) 0 2 1
1 1 2.99 1 1 2017-09-05 (NULL) 0 3 1
6 1 8.00 2 2 2017-09-27 (NULL) 0 1 2
5 1 4.00 1 2 2017-09-25 (NULL) 0 2 2
2 1 3.00 2 2 2017-09-10 (NULL) 0 3 2
Wykorzystanie tych wyników do wygenerowania średniej listy na dostawcę.
Zapytanie
SELECT
Expenses_ranked.supplier
, AVG(Expenses_ranked.cost / Expenses_ranked.quantity) AS AVG
FROM (
SELECT
*
, CASE
WHEN @supplier = supplier
THEN @rank := @rank + 1
ELSE @rank := 1
END
AS rank
, @supplier := supplier
FROM
Expenses
CROSS JOIN (
SELECT
@supplier := NULL
, @rank := 0
)
AS
init_user_params
WHERE
product_id = 1
ORDER BY
supplier ASC
, DATE DESC
)
AS Expenses_ranked
WHERE
Expenses_ranked.rank <= 3
GROUP BY
Expenses_ranked.supplier
Wynik
supplier avg
-------- --------------
1 2.4933333333
2 3.1666666667
Teraz możemy użyć prostego ORDER BY [] ASC LIMIT 1
aby uzyskać najtańszego dostawcę
Zapytanie
SELECT
Expenses_ranked_avg.supplier AS cheapest_supplier
FROM (
SELECT
Expenses_ranked.supplier
, AVG(Expenses_ranked.cost / Expenses_ranked.quantity) AS AVG
FROM (
SELECT
*
, CASE
WHEN @supplier = supplier
THEN @rank := @rank + 1
ELSE @rank := 1
END
AS rank
, @supplier := supplier
FROM
Expenses
CROSS JOIN (
SELECT
@supplier := NULL
, @rank := 0
)
AS
init_user_params
WHERE
product_id = 1
ORDER BY
supplier ASC
, DATE DESC
)
AS
Expenses_ranked
WHERE
Expenses_ranked.rank <= 3
GROUP BY
Expenses_ranked.supplier
)
AS Expenses_ranked_avg
ORDER BY
Expenses_ranked_avg.avg ASC
LIMIT 1
Wynik
cheapest_supplier
-------------------
1
Więcej optymalnych zapytań.
Co również możliwe jest deklarowanie zmiennych użytkownika w ramach instrukcji where. Dzięki temu możliwe jest bezpośrednie odfiltrowanie rankingu.
Zapytanie
SELECT
*
FROM
Expenses
WHERE
(
CASE
WHEN @supplier = supplier
THEN @rank := @rank + 1
ELSE @rank := 1
END
)
AND
(@supplier := supplier )
AND
@rank <= 3
AND
product_id = 1
ORDER BY
supplier ASC
, DATE ASC
Wynik
id product_id cost quantity supplier date
------ ---------- ------ -------- -------- ------------
1 1 2.99 1 1 2017-09-05
3 1 2.50 1 1 2017-09-20
4 1 3.98 2 1 2017-09-22
2 1 3.00 2 2 2017-09-10
5 1 4.00 1 2 2017-09-25
6 1 8.00 2 2 2017-09-27
Teraz korzystanie z tego zestawu wyników jest łatwe, aby znaleźć najtańszego dostawcę.
Zapytanie
SELECT
Expenses_ranked.supplier AS cheapest_supplier
FROM (
SELECT
*
FROM
Expenses
WHERE
(
CASE
WHEN @supplier = supplier
THEN @rank := @rank + 1
ELSE @rank := 1
END
) IS NOT NULL
AND
(@supplier := supplier ) IS NOT NULL
AND
@rank <= 3
AND
product_id = 1
ORDER BY
supplier ASC
, DATE ASC
)
AS Expenses_ranked
GROUP BY
Expenses_ranked.supplier
ORDER BY
AVG(Expenses_ranked.cost / Expenses_ranked.quantity) ASC
LIMIT 1
Wynik
cheapest_supplier
-------------------
1