🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
HiveQL

HiveQLは、Hive内の管理データを操作するのに使用されるSQL寄りのデータ操作言語です。HiveはHadoop上で動くソフトウェアで、HiveQLで記述した命令をMapReduceに自動に変換することができ、データ解析を容易に行うことが可能になります。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

解決済

1回答

2555閲覧

日付、ユーザごとに、特定アイテムをカウントしたい

Satomi07

総合スコア24

HiveQL

HiveQLは、Hive内の管理データを操作するのに使用されるSQL寄りのデータ操作言語です。HiveはHadoop上で動くソフトウェアで、HiveQLで記述した命令をMapReduceに自動に変換することができ、データ解析を容易に行うことが可能になります。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

0グッド

0クリップ

投稿2021/01/29 10:59

SQLのことで教えていただけませんか。

user_tblに、そのユーザが最も好きなアイテム(top1),2番目に好きなアイテム(top2)があります。
shopping_tblに、その日にユーザが得たアイテムが、日付順で1つずつ並んでいます。

user_tbl
|id|date|top_1|top_2|
|01|0101|item_a|item_b|
|01|0102|item_a|item_b|



|99|1231|item_c|item_b|

shopping_tbl
|id|date|item|
|01|0101|item_a|
|01|0101|item_a|
|01|0101|item_c|
|01|0101|item_b|



|99|1231|item_c|

上記から、各ユーザがその日に得たアイテムのうちtop1,top2に該当するものを集計してcount_tblを作りたいです。

count_tbl
|id|date|top1_count|top2_count|
|01|0101|2|1|
|01|0102|3|0|



|99|1231|4|0|

どなたか、お知恵を貸していただけないでしょうか。
最終的にはHiveに翻訳する予定ですが、SQLで教えていただければと思います。

いくつかクエリを流していますが、COUNT(item) OVER(PARTITION BY id, item)でうまくいかず、LEFT OUTER JOINではすべての列を出すことができなくて悩んでいます。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

errormaker74

2021/01/29 13:00

データベースはなんでしょうか?(Oracle?PostgreSQL?など) あとたいていのデータベースではdateは予約語なのでカラム名には使わないほうがよいでしょう。 一例ですが、下記のようなSELECT文で取れませんか?(Oracleを想定して書きました。dateは予約語なのでダブルクォーテーションで囲ってます) INSERT INTO SELECTのような方法でテーブルに挿入可能だと思います。 ``` SELECT ut.id ,ut."date" ,(SELECT COUNT(st.item) FROM shopping_tbl st WHERE st.id = ut.id AND st."date" = ut."date" AND st.item = ut.top_1) as top1_count ,(SELECT COUNT(st.item) FROM shopping_tbl st WHERE st.id = ut.id AND st."date" = ut."date" AND st.item = ut.top_2) as top2_count FROM user_tbl ut ```
Satomi07

2021/01/29 13:49 編集

ありがとうございます。 データベースはHiveですが、ヒントを頂いてHiveに翻訳しようかと思っていました。
Satomi07

2021/01/29 15:39

ありがとうございます、ただ、構成のヒントなどは使えますし、同じ部分もあります。 なによりHiveだけで回答をもらうより、多く知恵を頂けるので…。
errormaker74

2021/01/29 15:58

私も[SQL]のタグを削った方が良いと思います。 SQLにも方言や独特の機能がありますし、その知識を持って答えたとしてもHiveで使えないなら教える側の時間の無駄だと思います。
Satomi07

2021/01/29 16:11 編集

以前、質問して得たSQL文を、自分でhiveに翻訳してうまく行きました。コピーするつもりではないです。SQLも、まだ書きなれていないため、私には考え方がとても有益です。明日これで試してみます。
Orlofsky

2021/01/29 22:00

せっかくURLを提示したのに、読んでないか、読んでも理解できないようで。
Satomi07

2021/01/29 23:10 編集

すみません、一応両方の環境を自分で作って試しておりますし、自分でも調べてから質問していますから、このサイトもみました。 だから、コピーするためだけでない、翻訳すると書きました。 私は、クエリの構成法を知りたいのです。
guest

回答1

0

ベストアンサー

追記依頼を見たらHiveではなくても良さそうだったので、MySQLで回答しますが、
副問い合わせと条件付きcountでできると思います。

MySQL

1select query.id, query.date, count(query.item = top_1 or null) as top1_count, count(query.item = top_2 or null) as top2_count from ( 2select u.*, s.id as s_id, s.date as s_date, s.item from user_tbl u 3left outer join shopping_tbl s on u.id = s.id and u.date = s.date and (u.top_1 = s.item or u.top_2 = s.item) 4) query 5group by query.id, query.date;
テストデータ
-- DDL CREATE TABLE `shopping_tbl` ( `id` int NOT NULL, `date` varchar(4) DEFAULT NULL, `item` varchar(45) DEFAULT NULL ); CREATE TABLE `user_tbl` ( `id` int NOT NULL, `date` varchar(4) DEFAULT NULL, `top_1` varchar(45) DEFAULT NULL, `top_2` varchar(45) DEFAULT NULL ); -- データ INSERT INTO user_tbl VALUES (1,'0101','item_a','item_b'); INSERT INTO user_tbl VALUES (1,'0102','item_a','item_b'); INSERT INTO user_tbl VALUES (1,'0103','item_c','item_b'); INSERT INTO user_tbl VALUES (99,'1231','item_c','item_b'); INSERT INTO shopping_tbl VALUES (1,'0101','item_a'); INSERT INTO shopping_tbl VALUES (1,'0101','item_a'); INSERT INTO shopping_tbl VALUES (1,'0101','item_c'); INSERT INTO shopping_tbl VALUES (1,'0101','item_b'); INSERT INTO shopping_tbl VALUES (1,'0102','item_a'); INSERT INTO shopping_tbl VALUES (1,'0102','item_a'); INSERT INTO shopping_tbl VALUES (1,'0102','item_a'); INSERT INTO shopping_tbl VALUES (1,'0103','item_a'); INSERT INTO shopping_tbl VALUES (1,'0103','item_b'); INSERT INTO shopping_tbl VALUES (1,'0103','item_a'); INSERT INTO shopping_tbl VALUES (99,'1231','item_c');
結果
iddatetop1_counttop2_count
1010121
1010230
1010301
99123110

投稿2021/01/30 03:35

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Satomi07

2021/02/03 07:42

SochiAdachi様、ご回答ありがとうございます。 left outer joinならHiveで行けます、大変助かりました。 教えていただいたクエリを基にHiveに翻訳して、下記で回すことができました。 SELECT user_tbl.id, user_tbl.date_, SUM(IF(user_tbl.top_1=shopping_tbl.item,1,0)) AS top1_count, SUM(IF(user_tbl.top_2=shopping_tbl.item,1,0)) AS top2_count FROM user_tbl LEFT OUTER JOIN shopping_tbl ON(user_tbl.id=shopping_tbl.id AND user_tbl.date_=shopping_tbl.date_) GROUP BY user_tbl.id,user_tbl.date_ errormaker74様、Orlofsky様にも感謝を。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問