MySQL練習練習5||NiuKeのコース順序分析

はじめに:タイトルは、NiukeのオンラインプログラミングSQLプラクティスに由来します。記事の内容は、主にブロガーのアイデア、関連する洞察、および質問を行う際の要点の要約を説明することです。一般的に、明確なバグは簡単に修正でき、隠れたバグを見つけるのは難しく、まだまだ先は長いです。検索します。

1.質問1(難易度:簡単)

注文情報テーブル(order_info)があり、概要は次のとおりです。

1行目は、user_idが557336のユーザーが、client_idが1のクライアントを使用して2025-10-10にC ++コースを注文したが、ステータスは購入に失敗したことを示しています。

2行目は、user_idが230173543のユーザーが、client_idが2のクライアントを使用して2025-10-12にPythonコースを注文し、ステータスが購入に成功したことを示しています。

。。。。

最後の行は、user_idが557336のユーザーが、client_idが1のクライアントを使用して2025-10-24にPythonコースを注文し、ステータスが購入に失敗したことを示しています。

ライティング要件:

2025-10-15以降に正常に購入されたC++コース、Javaコース、またはPythonの順序をクエリするSQLステートメントを記述し、order_infoのIDで昇順で並べ替えてください。上記の例のクエリ結果は次のとおりです。次のとおりです。

 問題解決のアイデア:

 問題解決コード:

select *
from order_info
where date>'2025-10-15'
and status='completed'
and product_name in ('C++','Java','Python')
order by id;

比較の要約:

  • この質問は比較的単純で、主にスクリーニングと並べ替えを調べます。

2.質問内容2 (難易度:中)

注文情報テーブル(order_info)があり、概要は次のとおりです。

1行目は、user_idが557336のユーザーが、client_idが1のクライアントを使用して2025-10-10にC ++コースを注文したが、ステータスは購入に失敗したことを示しています。

2行目は、user_idが230173543のユーザーが、client_idが2のクライアントを使用して2025-10-12にPythonコースを注文し、ステータスが購入に成功したことを示しています。

。。。。

最後の行は、user_idが557336のユーザーが、client_idが1のクライアントを使用して2025-10-25にC ++コースを注文したことを示しており、ステータスは購入が成功したことです。

ライティング要件:

2025-10-15以降にクエリを実行するSQLステートメントを記述して、同じユーザーが2つ以上を注文し、購入に成功したC ++コース、Javaコース、またはPythonコースのuser_idを、昇順で並べ替えてください。上記の例クエリの結果は次のとおりです(説明:id 4と6の順序は上記の条件を満たす、出力の対応するuser_idは57、id5と7の順序は上記の条件を満たす、出力の対応するuser_idは557336です。user_idで昇順でソートします。):

問題解決のアイデア:

  問題解決コード:

select user_id
from order_info
where date>'2025-10-15'
and status='completed'
and product_name in ('C++','Python','Java')
group by user_id
having count(user_id)>=2
order by user_id;

比較の要約:

  • 最初の質問と比較して、質問にはもう1つのグループスクリーニングが必要です。難しいのは、グループ前スクリーニングかグループ後スクリーニングかを区別することです。
  • グループ化する前にフィルタリングするためのキーワードはwhereであり、これは集計関数(count、minなど)では使用されません。
  • グループ化後のフィルタリングのキーワードは、集計関数で一般的に使用されるhaingです。

3.質問内容3(難易度:中)

注文情報テーブル(order_info)があり、概要は次のとおりです。

1行目は、user_idが557336のユーザーが、client_idが1のクライアントを使用して2025-10-10にC ++コースを注文したが、ステータスは購入に失敗したことを示しています。

2行目は、user_idが230173543のユーザーが、client_idが2のクライアントを使用して2025-10-12にPythonコースを注文し、ステータスが購入に成功したことを示しています。

。。。。

最後の行は、user_idが557336のユーザーが、client_idが1のクライアントを使用して2025-10-25にC ++コースを注文したことを示しており、ステータスは購入が成功したことです。

ライティング要件:

2025-10-15以降に同じユーザーによって配置された2つ以上のC++コース、Javaコース、またはPythonコースの注文情報を照会するSQLステートメントを記述してください。注文情報は、order_infoのIDに従って昇順で並べ替えられます。 、上記の例のクエリ結果は次のとおりです(説明:ID 4および6の注文は上記の条件を満たし、対応する情報を出力します。id5および7の注文は上記の条件を満たし、対応する情報を出力します。 IDで昇順で並べ替えます。):

問題解決のアイデア:

 問題解決コード:

select *
from order_info
where date>'2025-10-15'
and status='completed'
and product_name in ('C++','Python','Java')
and user_id in (
    select user_id
    from order_info
    where date>'2025-10-15'
    and status='completed'
    and product_name in ('C++','Python','Java')
    group by user_id
    having count(user_id)>=2)
order by id;

比較の要約:

  • group byは、データの最初の行のみを返します。

  • 2番目の質問と比較すると、質問は修飾されたuser_idのクエリから修飾された注文情報のクエリに変更されているため、グループ化集計関数の誤った使用につながる可能性があります。エラーコードは次のとおりです。
    # 错误示例:
    select *
    from order_info
    where product_name in ('C++','Java','Python')
    and status='completed'
    and date >'2025-10-15'
    group by user_id
    having count(*)>=2
    order by id;

4.質問4(難易度:難易度)

注文情報テーブル(order_info)があり、概要は次のとおりです。

1行目は、user_idが557336のユーザーが、client_idが1のクライアントを使用して2025-10-10にC ++コースを注文したが、ステータスは購入に失敗したことを示しています。

2行目は、user_idが230173543のユーザーが、client_idが2のクライアントを使用して2025-10-12にPythonコースを注文し、ステータスが購入に成功したことを示しています。

。。。。

最後の行は、user_idが557336のユーザーが、client_idが1のクライアントを使用して2025-10-25にPythonコースを注文し、ステータスが購入に成功したことを示しています。

ライティング要件:

2025-10-15以降にクエリを実行するsqlステートメントを記述してください。ユーザーが2つ以上のC++コース、Javaコース、またはPythonコースを注文し、購入が成功した場合は、このユーザーのuser_idを出力し、上記の条件でC++コースまたはJavaコースまたはPythonコースを最初に正常に購入したfirst_buy_date、および成功したC++コースまたはJavaコースまたはPythonコースを購入した回数。出力結果はuser_idの昇順で並べ替えられます。 、上記の例の結果次のようになります(説明:ID 4および6の注文は上記の条件を満たし、出力は57、ID 4の注文は最初の正常な購入であり、出力first_buy_dateは2025年10月23日です。合計2つの成功した購入。IDは5、7、8の注文が上記の条件を満たす、出力は557336、ID 5の注文は最初の成功した購入、出力first_buy_dateは2025年10月23日、合計3成功した購入。)

問題解決のアイデア:

問題解決コード:

select user_id,min(date) as first_buy_date,count(user_id) as cnt
from order_info
where date>'2025-10-15'
and status='completed'
and product_name in ('C++','Python','Java')
group by user_id
having count(user_id)>=2
order by user_id;

比較の要約:

  • selectは、このトピックのcountやminなどの複数の集計関数で使用できます
  • 2番目の質問と比較すると、この質問の要件は、関連する条件を満たす購入日と回数を照会することであり、集計関数の使用に焦点が当てられています。

5.質問5(難易度:難易度)

注文情報テーブル(order_info)があり、概要は次のとおりです。

1行目は、user_idが557336のユーザーが、client_idが1のクライアントを使用して2025-10-10にC ++コースを注文したが、ステータスは購入に失敗したことを示しています。

2行目は、user_idが230173543のユーザーが、client_idが2のクライアントを使用して2025-10-12にPythonコースを注文し、ステータスが購入に成功したことを示しています。

。。。。

最後の行は、user_idが557336のユーザーが、client_idが1のクライアントを使用して2025-10-26にPythonコースを注文し、ステータスが購入に成功したことを示しています。

ライティング要件:

2025-10-15以降にクエリを実行するsqlステートメントを記述してください。ユーザーが、購入ステータスが成功した2つ以上のC ++コース、Javaコース、またはPythonコースを注文した場合、このユーザーのuser_idを出力し、First_buy_dateを満たします。上記の条件を満たすC++コースまたはJavaコースまたはPythonコースの最初の購入の成功と、前述の条件を満たすC++コースまたはJavaコースまたはPythonコースの2回目の購入のsecond_buy_dateおよびC++コースの購入の成功または、JavaコースまたはPythonコースのcntの回数、および出力結果がuser_idの昇順で並べ替えられます。上記の例のクエリ結果は次のとおりです(説明:id4および6の順序は上記の条件を満たす。出力57、ID 4の注文が最初の購入成功した場合、出力first_buy_dateは2025-10-23、ID 6の注文は2回目の購入、出力second_buy_dateは2025-10-24、合計2つの成功した購入のうち、ID 5、7、8の注文は上記の条件を満たす、出力は557336、ID 5の注文は最初の購入に成功、出力first_buy_dateは2025-10-23、ID7の注文は2回目の購入で、出力second_buy_dateは2025-10-25で、合計3回の購入が成功しました。

問題解決のアイデア:

問題解決コード:

WITH base_table AS (
    SELECT *,DENSE_RANK() over (partition by user_id order by date) AS rnk
    FROM order_info
    WHERE date>'2025-10-15'
    AND status='completed'
    AND product_name IN ('C++','Java','Python')
),
table1 AS (
    SELECT user_id, date as first_buy_date
    FROM base_table
    WHERE rnk=1
),
table2 AS (
    SELECT user_id, date as second_buy_date
    FROM base_table
    WHERE rnk=2
),
table3 AS (
    SELECT user_id, COUNT(user_id) AS cnt
    FROM base_table
    GROUP BY user_id
    HAVING cnt>=2
)
SELECT DISTINCT base_table.user_id,first_buy_date,second_buy_date,cnt
FROM base_table,table1,table2,table3
WHERE base_table.user_id=table1.user_id
AND base_table.user_id=table2.user_id
AND base_table.user_id=table3.user_id
ORDER BY base_table.user_id

比較の要約:

  • 上記の問題解決のアイデアは理解しやすいですが、記述されたコードは非常に長いため、コードをさらに最適化して単純さを向上させることができます。最適化のアイデアとコードは次のとおりです。次の図では、MAX(second_buy_date)をMIN(second_buy_date)に置き換えることもできます。本質は、second_buy_dateの集計関数を使用してGROUPBY句を処理することです。

WITH table1 AS (
    SELECT order_info.user_id, order_info.date as second_buy_date,
    DENSE_RANK() over (partition by user_id order by date) AS rnk
    FROM order_info
    WHERE date>'2025-10-15'
    AND status='completed'
    AND product_name IN ('C++','Java','Python')
)
SELECT order_info.user_id, MIN(order_info.date) AS first_buy_date,
MAX(second_buy_date), COUNT(*) AS cnt
FROM order_info INNER JOIN table1 ON order_info.user_id=table1.user_id
WHERE date>'2025-10-15'
AND status='completed'
AND product_name IN ('C++','Java','Python')
AND rnk=2
GROUP BY order_info.user_id
HAVING cnt>=2
ORDER BY order_info.user_id
  • コメント領域で他のソリューションを参照すると、並べ替え関数のランクとif関数を使用すると、より簡潔で効率的になります。

  • さらに、リード関数を使用して、2番目の購入日を最初の場所に移動することもできます。リード関数には3つのパラメーターがあり、最初のパラメーターは列名、2番目のパラメーターはオフセットオフセット、3番目のパラメーターはオフセットオフセットです。パラメータは、レコードウィンドウを超えたときのデフォルト値です。参照領域の解決策は次のとおりです。


6.質問6(難易度:中程度)

注文情報テーブル(order_info)があり、概要は次のとおりです。

1行目は、user_idが557336のユーザーが、client_idが1のクライアントを使用して、2025-10-10にC ++コースの非グループ(is_group_buyはNo)注文を行ったことを示していますが、ステータスは購入が成功しなかったことです。 。

2行目は、user_idが230173543のユーザーが、client_idが2のクライアントを使用して、2025-10-12にPythonコースの非グループ(is_group_buyはNo)の注文を行い、ステータスが購入に成功したことを示しています。

。。。。

最後の行は、user_idが557336のユーザーが、2025-10-25のC ++コースのグループ化の順序(is_group_buyはYes)を使用したことを示しています。グループ化はクライアントをカウントしないため、client_idは0であり、ステータスは購入は成功しました。

クライアントテーブル(client)があり、概要は次のとおりです。

ライティング要件:

2025-10-15以降にクエリを実行するSQLステートメントを記述してください。同じユーザーが2つ以上の注文を行ったC++コース、Javaコース、またはPythonコースの注文ID、グループ化されているかどうか、クライアントの名前情報、最後の列がグループ以外の注文の場合は、対応するクライアント名が表示され、グループの注文の場合はNULLが表示され、order_infoのIDに従って昇順で並べ替えられます。上記の条件を満たすため、 4はIOSを介して行われた非グループ注文であり、対応する情報を出力します。6は、PCを介して行われた非グループ注文であり、対応する情報とクライアント名を出力します。idは5、7です。注文は上記の条件を満たすため、5および7はグループ順序であり、対応する情報とNULLを出力します。IDで昇順で並べ替えます):

問題解決のアイデア:

 問題解決コード:

select order_info.id,order_info.is_group_buy,if(is_group_buy='Yes',null,client.name)
from order_info
left join client
on order_info.client_id=client.id
where date>'2025-10-15'
and product_name in ('C++','Python','Java')
and status='completed'
and user_id in (
    select user_id
    from order_info
    where date>'2025-10-15'
    and product_name in ('C++','Python','Java')
    and status='completed'
    group by user_id
    having count(user_id)>=2)
order by order_info.id;

比較の要約:

  • 上記の解決策は、タイトルの説明に従って問題を解決することです。タイトルは不器用で、主にマルチテーブルの結合とサブクエリを使用します。
  • ウィンドウ関数を使用してコードを最適化する

select table1.id, table1.is_group_buy, client.name
from (
    select *, count(*) over(partition by user_id) as cnt
    from order_info
    where date>'2025-10-15'
    and product_name in ('C++','Java','Python')
    and status='completed'
) as table1
left join client on table1.client_id=client.id
where table1.cnt>=2
order by table1.id

セブン、トピックセブン(難易度:難しい)

注文情報テーブル(order_info)があり、概要は次のとおりです。

1行目は、user_idが557336のユーザーが、client_idが1のクライアントを使用して、2025-10-10にC ++コースの非グループ注文(is_group_buyはNo を行ったことを示していますが、ステータスは成功していない。

2行目は、user_idが230173543のユーザーが、2025-10-12にclient_idが2のクライアントを使用して、Pythonコースの非グループ注文(is_group_buyはNo)を行いステータス購入に成功したことを示しています。

。。。。

最後の行は、user_idが557336のユーザーが、2025-10-25のC ++コースのグループ化(is_group_buyYes)の順序を使用したことを示しています。グループ化はクライアントをカウントしないため、client_id0であり、ステータスは購入です。成功しています。

クライアントテーブル(client)があり、概要は次のとおりです。

ライティング要件:

2025-10-15以降に同じユーザーによって配置されたC++コース、Javaコース、またはPythonコースのソース情報を照会するSQLステートメントを記述してください。最初の列にはクライアント名が表示されます。グループオーダーの場合は、GroupBuyが表示されます。 、2番目の列は、このクライアント(またはグループ注文)の注文数を示し、最終結果は最初の列(ソース)に従って昇順で並べ替えられます。上記の例のクエリ結果は次のとおりです(説明:注文id 4および6は上記の条件を満たし、4はIOSを介して行われた非グループ注文であるため、記録:IOS 1、6はPCを介して行われた非グループ注文であり、次に記録:PC 1;id5および7の注文上記の条件を満たし、5と7はグループ注文であるため、次のように記録します。GroupBuy 2;最後にソースの昇順で並べ替えます。):

問題解決のアイデア:

問題解決コード:

select if(client.name is null,'GroupBuy',client.name) as source,count(client_id) as cnt
from order_info
left join client
on order_info.client_id=client.id
where date>'2025-10-15'
and status='completed'
and product_name in ('C++','Python','Java')
and user_id in (
    select user_id
    from order_info
    where date>'2025-10-15'
    and status='completed'
    and product_name in ('C++','Python','Java')
    group by user_id
    having count(user_id)>=2)
group by client_id
order by source

比較の要約:

  • 前の質問に基づいて、この質問は注文数のクエリを追加します。前の質問の正しい基礎があれば、この質問の難易度は大幅に軽減されます。重要なポイントは、グループの注文を判断するために何を使用するかです。
  • ウィンドウ関数を使用して解決する場合は、このクエリに基づいてcntとしてcount(client_id)を追加し、わずかに変更します。

select if(client.name is null,'GroupBuy',client.name) as source,count(client_id) as cnt
from (
    select *, count(*) over(partition by user_id) as cnt
    from order_info
    where date>'2025-10-15'
    and product_name in ('C++','Java','Python')
    and status='completed'
) as table1
left join client on table1.client_id=client.id
where table1.cnt>=2
group by source
order by source

おすすめ

転載: blog.csdn.net/Inochigohan/article/details/119678107