mysql - 1 つの SQL ステートメントで max、group by、where、order by をどのように記述すればよいですか?

okwaves2024-01-25  7

1996 年に最も多くの注文を開始した顧客 ID を見つける必要があります。そして、次のステートメントを書きました。

SELECT count(orderID) as orderNumber
     , CustomerID
     , OrderDate  
  FROM Orders 
 where OrderDate between "1996-01-01" AND "1996-12-31" 
 group 
    by CustomerID 
 order 
    by orderNumber DESC ;

結果は以下の通りです:

私の質問は、先頭の customerID である 65,63,20 を出力したいだけですが、その書き方がわかりません。 ここで max を使用して、6 つの注文を開始した customerID をフィルタリングすると思います。 私は正しいでしょうか?

まずトップシスナーをどのような基準で定義し、その情報をどのように入手しているかを示してください。

– nbk

2020 年 9 月 4 日 18:55

meta.stackoverflow.com/questions/333952/… を参照してください。

– ストロベリー

2020 年 9 月 4 日 18:56

1

あなたのクエリは無効です。どの OrderDate を表示しますか?顧客にとって最初のものですか、それとも最後のものですか?適切な関数を決定して適用します。 MAX(OrderDate) か、日付をまったく表示しません。上位の顧客だけを表示したい場合は、LI を使用してくださいORDER BY 句の後に MIT 1 を追加します。

– トーステン・ケトナー

2020 年 9 月 4 日 21:38

@ThorstenKettner。私のクエリは有効です。 1996 年のすべての注文をフィルタリングしたいと考えています。注文日は、顧客が注文を開始した日と一致します。したがって、1 つの customerId が orderDate を持つ複数の orderId を持つことができます。ここに問題があります。同じ最大注文を開始した customerId が 3 つあります。 LIMIT 1 を使用すると、customerId が 1 つだけ返されます

– リリアン

2020 年 9 月 4 日 22:11

いいえ、クエリは無効です。顧客 65 は 6 件の注文を出しており、日付は「1996-07-22」と表示されています。つまり、6 件の注文すべてがその日に行われたことが保証されていることがわかりますか?あなたのテーブルはそれを保証しますか? MySQL はここでエラーを発生させるはずですが、古いバージョンを実行していることを示すものではない可能性があります。前述したように、クエリを有効にするには、select 句から日付を削除するか、集計関数を適用する必要があります。

– トーステン・ケトナー

2020 年 9 月 5 日 6:27



------------------------

MySQL 8.0 では、rank()

select *
from (

    select count(*) as orderNumber
         , CustomerID
         , max(OrderDate) 
         , rank() over(order by count(*) desc) rn
     from Orders 
     where OrderDate >= '1996-01-01' and OrderDate < '1997-01-01'
     group by CustomerID 
) t
where rn = 1

メモ:

select 句の OrderDate は group by 句に属していないため、集計関数が必要です

日付に時間要素がある場合は、間隔よりも半分開いた間隔の方が適しています

リテラル文字列には二重引用符ではなく一重引用符を使用します



------------------------

バージョン 8 より前の MySQL バージョンでは、カウントを 2 回行う必要がありました。例:

select 
  count(orderid) as number_of_orders,
  customerid,
  group_concat(orderdate order by orderdate) as order_dates
from orders 
where orderdate between date '1996-01-01' and date '1996-12-31'
group by customerid 
having number_of_orders =
(
  select max(number_of_orders)
  from
  (
    select count(orderid) as number_of_orders
    from orders 
    where orderdate between date '1996-01-01' and date '1996-12-31'
    group by customerid 
  ) counted
)
order by customerid;

総合生活情報サイト - OKWAVES
総合生活情報サイト - OKWAVES
生活総合情報サイトokwaves(オールアバウト)。その道のプロ(専門家)が、日常生活をより豊かに快適にするノウハウから業界の最新動向、読み物コラムまで、多彩なコンテンツを発信。