私は経費テーブルの最新3つのentiresの 項目(コスト/数量)あたりの平均コストに基づいて、特定の製品の最も安い業者を把握することができMYSQLクエリを書きたいです (日付に基づく)
これは、日付に基づいてランキングを生成するためにユーザー変数で動作するクエリを必要とします。 最後の3つの日付のみを選択してください。
クエリ
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
結果結果はサプライヤーごとの平均のリストを生成することを使用し
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
。
クエリ
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
結果
supplier avg
-------- --------------
1 2.4933333333
2 3.1666666667
今、私たちは、最も安いサプライヤーに
クエリを取得するには、単純なORDER BY [] ASC LIMIT 1
を使用することができます
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
結果
cheapest_supplier
-------------------
1
より最適なクエリ。
where変数内でユーザー変数を宣言することも可能です。 ランキングを除外することを直接可能にします。
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
クエリ
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
結果は、今では使用安い業者を見つけるために、この結果セットは簡単です。
クエリ
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
結果
cheapest_supplier
-------------------
1
は、我々はこの仕事での試みを見ることはできますか?あなたの最初のことは、 'ORDER BY 'と' LIMIT 3'の 'Supplier'と' Expenses'の間のジョイントのように見えます。 2番目の同様のクエリを実行することによって平均を行うことはできますが、平均関数を使用します(マニュアルに記載されています)。 – halfer
ありがとう、@halferこれは私が持っている限りです。製品から code'select *が INNERはON経費を登録しようproducts.id = expenses.product AND products.item = '1'(expenses.cost/expenses.quantity) LIMIT 3 BY ORDER; ' –
すべての経費IDSなぜですか? – Strawberry