記入日:2023-01-27 編集日:2023-01-27
SQL見るだけクエリ。今回は、
以前書いた、商品別に日ごとの売上額を集計CASE文を使ってクロス集計したSQLと、
ここ数回の、FIND_IN_SETを使って順位番号をつけるSQLをミックスしたものを書いてみたいと思います。
以下のsql_orderテーブルには、販売商品毎のレコードが入っております。
テーブル名:sql_order
| id | order_id | name | item_id | price | quantity | size | datetime | status |
|---|---|---|---|---|---|---|---|---|
| 1 | 1 | 伊藤 明日香 | sku-0001 | 3000 | 1 | S | 2022-12-16 07:00:00 | 1 |
| 2 | 1 | 伊藤 明日香 | sku-0002 | 2500 | 3 | S | 2022-12-16 07:00:00 | 1 |
| 3 | 1 | 伊藤 明日香 | sku-0003 | 9000 | 1 | S | 2022-12-16 07:00:00 | 1 |
| 4 | 2 | 原田 和美 | sku-0001 | 3000 | 1 | L | 2022-12-16 10:00:00 | 1 |
| 5 | 2 | 原田 和美 | sku-0002 | 2500 | 1 | L | 2022-12-16 10:00:00 | 1 |
| 6 | 2 | 原田 和美 | sku-0003 | 9000 | 2 | L | 2022-12-16 10:00:00 | 1 |
| 7 | 3 | 高橋 由美子 | sku-0001 | 3000 | 1 | M | 2022-12-16 18:00:00 | 1 |
| 8 | 3 | 高橋 由美子 | sku-0002 | 2500 | 5 | S | 2022-12-16 18:00:00 | 1 |
| 9 | 3 | 高橋 由美子 | sku-0003 | 9000 | 1 | M | 2022-12-16 18:00:00 | 1 |
| 10 | 4 | 田中 明日香 | sku-0001 | 3000 | 1 | S | 2022-12-16 22:00:00 | 1 |
| 11 | 4 | 田中 明日香 | sku-0002 | 2500 | 1 | S | 2022-12-16 22:00:00 | 1 |
| 12 | 4 | 田中 明日香 | sku-0003 | 9000 | 2 | S | 2022-12-16 22:00:00 | 1 |
| 13 | 5 | 小林 美佐子 | sku-0001 | 3000 | 1 | L | 2022-12-17 10:00:00 | 1 |
| 14 | 5 | 小林 美佐子 | sku-0002 | 2500 | 1 | L | 2022-12-17 10:00:00 | 1 |
| 15 | 5 | 小林 美佐子 | sku-0003 | 9000 | 2 | L | 2022-12-17 10:00:00 | 1 |
| 16 | 6 | 渡辺 雄一 | sku-0001 | 3000 | 1 | S | 2022-12-18 08:00:00 | 1 |
| 17 | 6 | 渡辺 雄一 | sku-0002 | 2500 | 1 | S | 2022-12-18 08:00:00 | 1 |
| 18 | 6 | 渡辺 雄一 | sku-0003 | 9000 | 1 | S | 2022-12-18 08:00:00 | 1 |
| 19 | 7 | 佐藤 智子 | sku-0001 | 3000 | 12 | M | 2022-12-18 15:00:00 | 1 |
| 20 | 7 | 佐藤 智子 | sku-0002 | 2500 | 1 | S | 2022-12-18 15:00:00 | 1 |
| 21 | 7 | 佐藤 智子 | sku-0003 | 9000 | 1 | M | 2022-12-18 15:00:00 | 1 |
| 22 | 8 | 坂本 純子 | sku-0001 | 3000 | 1 | S | 2022-12-19 20:00:00 | 1 |
| 23 | 8 | 坂本 純子 | sku-0002 | 2500 | 1 | S | 2022-12-19 20:00:00 | 1 |
| 24 | 8 | 坂本 純子 | sku-0003 | 9000 | 3 | S | 2022-12-19 20:00:00 | 1 |
| 25 | 9 | 加藤 和子 | sku-0001 | 3000 | 1 | L | 2022-12-20 10:00:00 | 1 |
| 26 | 9 | 加藤 和子 | sku-0002 | 2500 | 8 | L | 2022-12-20 10:00:00 | 1 |
| 27 | 9 | 加藤 和子 | sku-0003 | 9000 | 1 | L | 2022-12-20 10:00:00 | 1 |
| 28 | 10 | 山口 晴子 | sku-0001 | 3000 | 1 | M | 2022-12-20 19:00:00 | 1 |
| 29 | 10 | 山口 晴子 | sku-0002 | 2500 | 1 | L | 2022-12-20 19:00:00 | 1 |
| 30 | 10 | 山口 晴子 | sku-0003 | 9000 | 3 | L | 2022-12-20 19:00:00 | 1 |
この記事を読むと(約5分)
SQLを使って、商品毎の日別の売上を集計しつつ、商品毎に日別のランキングを取得する方法がわかります。
今回は、直にSQL文を書くとかなり長くなってしまいそうでしたので、SQLの一部をプログラムで事前に生成する書き方にしました。
今回も使う関数的には、前回同様、FIND_IN_SETやGROUP_CONCATです。 これらと副問合せ(サブクエリ)、CASE文などを組み合わせて、ランキングの値を導きます。
少し複雑な内容になりますのでなんとなく雰囲気が伝われば良いかなと思っております。
try {
include_once '../model/class.php';
$query_source = NULL;
$items = array('sku-0001', 'sku-0002', 'sku-0003');
foreach($items as $i => $item_id) {
$query_source .= '
SUM(CASE WHEN item_id = "' . $item_id . '"
THEN price*quantity ELSE 0 END) AS "payment_' . ($i + 1) . '" ,
FIND_IN_SET(SUM(CASE WHEN item_id = "' . $item_id . '"
THEN price*quantity ELSE 0 END),(
SELECT GROUP_CONCAT(payment_' . ($i + 1) . ')
FROM(
SELECT DATE(datetime) AS date ,
SUM(CASE WHEN item_id = "' . $item_id . '"
THEN price*quantity ELSE 0 END) AS payment_' . ($i + 1) . '
FROM sql_order
GROUP BY date
ORDER BY payment_' . ($i + 1) . ' DESC
) AS payment_' . ($i + 1) . '_array
)) AS rank_' . ($i + 1) . ',
';
}
// データベース接続
$database = new Database();
$db = $database->connect();
// SQLを準備し、パラメータをバインドする
$query = 'SELECT DATE(datetime) AS date ,
' . $query_source . '
SUM(price*quantity) AS "total"
FROM sql_order
GROUP BY date';
$stmt = $db->prepare($query);
// 実行する
$stmt->execute();
// 結果を取得する
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
print_r($result);
// データベースから切断する
$database->disconnect();
} catch(PDOException $e) {
echo $e->getMessage();
}
これを実行すると、二次元連想配列で、取得することができます。
Array
(
[0] => Array
(
[date] => 2022-12-16
[payment_1] => 12000
[rank_1] => 2
[payment_2] => 25000
[rank_2] => 1
[payment_3] => 54000
[rank_3] => 1
[total] => 91000
)
[1] => Array
(
[date] => 2022-12-17
[payment_1] => 3000
[rank_1] => 4
[payment_2] => 2500
[rank_2] => 4
[payment_3] => 18000
[rank_3] => 4
[total] => 23500
)
[2] => Array
(
[date] => 2022-12-18
[payment_1] => 39000
[rank_1] => 1
[payment_2] => 5000
[rank_2] => 3
[payment_3] => 18000
[rank_3] => 4
[total] => 62000
)
[3] => Array
(
[date] => 2022-12-19
[payment_1] => 3000
[rank_1] => 4
[payment_2] => 2500
[rank_2] => 4
[payment_3] => 27000
[rank_3] => 3
[total] => 32500
)
[4] => Array
(
[date] => 2022-12-20
[payment_1] => 6000
[rank_1] => 3
[payment_2] => 22500
[rank_2] => 2
[payment_3] => 36000
[rank_3] => 2
[total] => 64500
)
)
| 日付 | sku-0001 | 順 | sku-0002 | 順 | sku-0003 | 順 | 合計数 |
|---|---|---|---|---|---|---|---|
2022-12-16 |
12,000 |
2 |
25,000 |
1 |
54,000 |
1 |
91,000 |
2022-12-17 |
3,000 |
4 |
2,500 |
4 |
18,000 |
4 |
23,500 |
2022-12-18 |
39,000 |
1 |
5,000 |
3 |
18,000 |
4 |
62,000 |
2022-12-19 |
3,000 |
4 |
2,500 |
4 |
27,000 |
3 |
32,500 |
2022-12-20 |
6,000 |
3 |
22,500 |
2 |
36,000 |
2 |
64,500 |
SQLの使いどころ
サイトに大量の情報を掲載することは、ユーザーにとってとても便利なことです。しかし、情報が多すぎると、目的の情報を見つけるのが困難になります。そのため、SQLを使用することで、情報を効率的に管理することができます。
SQLを使用することで、データベース内の情報を検索したり、フィルタリングしたりすることができます。これにより、ユーザーは目的の情報をスムーズかつ簡単に見つけることができます。
また、SQLを使用することで、データを集計したり、統合したりすることもできます。これにより、ユーザーはさまざまな視点から情報を分析することができます。つまり、サイトに多くの情報を掲載することが重要である一方で、その情報を効率的かつ簡単に管理することが求められる場合には、SQLが不可欠であるといえます。
KK
機械工学を専攻。工業デザイナーとして、国内及び海外の自動車・搬送ラインの設計などに従事した後、2003年にウェブシステム会社を設立。UI設計やウェブシステムの開発、DX化のディレクションなどを行っています。