質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.48%
BigQuery

BigQueryは、Google Cloud Platformが提供しているビッグデータ解析サービス。数TB(テラバイト)またはPB(ペタバイト)の膨大なデータに対し、SQL風のクエリを実行し、高速で集計・分析を行うサービスです。

SQL

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

Q&A

1回答

780閲覧

【SQL】二つのテーブルを結合する方法

Jonathan_Sf

総合スコア13

BigQuery

BigQueryは、Google Cloud Platformが提供しているビッグデータ解析サービス。数TB(テラバイト)またはPB(ペタバイト)の膨大なデータに対し、SQL風のクエリを実行し、高速で集計・分析を行うサービスです。

SQL

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

0グッド

0クリップ

投稿2022/11/10 01:39

編集2022/11/16 04:40

初学者です。お世話になります。
下記のように二つのテーブルを結合したいのですが、上手い方法が分かりません。
使うべき構文などをご教示いただけないでしょうか。具体的には「購入日時点における、最新の終値」を結合させるところで詰まっています。

何卒よろしくお願いします。

概要

 BigQueryを使っています。

  • 二つのテーブルを結合したい。
  • テーブルA(closing_price)は株価終値テーブル(日付、銘柄id、終値)
    • 1日ごとの終値を記録したもの。
  • テーブルB(contract)は株式購入テーブル(購入日、購入者id、購入銘柄id、購入時株価、購入口数)
    • 購入した株の情報を記録したもの。
  • テーブルBにテーブルAを左外部結合して、「購入日時点における、最新の終値を持つ行」を結合したい。

やりたいこと

  • 例えば下記のようなサンプルデータがあります。
CREATE TABLE `project.test.closing_price` ( date DATE NOT NULL, stock_id INT64 NOT NULL, closing_price INT64 NOT NULL, ); INSERT INTO `project.test.closing_price` ( date, stock_id,closing_price ) VALUES ("2022-10-21",1,1501), ("2022-10-22",1,1502), ("2022-10-23",1,1503), ("2022-10-24",1,1504), ("2022-10-25",1,1505); CREATE TABLE `project.test.contract` ( contract_date DATE NOT NULL, user_id INT64 NOT NULL, stock_id INT64 NOT NULL, stock_price INT64 NOT NULL, units INT64 NOT NULL, ); INSERT INTO `project.test.contract` ( contract_date, user_id, stock_id, stock_price,units ) VALUES ("2022-10-21",1,1,1501,1), ("2022-10-22",1,1,1502,1), ("2022-10-23",1,1,1503,1), ("2022-10-24",1,1,1504,1), ("2022-10-25",1,1,1505,1), ("2022-10-26",1,1,1506,1), ("2022-10-27",1,1,1507,1), ("2022-10-28",1,1,1508,1), ("2022-10-29",1,1,1509,1), ("2022-10-30",1,1,1510,1);
  • 例えば下記のようなSQLを実行すると、当然ですが、「購入日時点における、最新の終値を持つ行」だけでなく、「購入日以前の終値を持つ行」全てと結合されてしまいます。
SELECT * FROM `project.test.contract` AS A LEFT JOIN `project.test.closing_price` AS B ON A.stock_id = B.stock_id and A.contract_date > B.date order by A.contract_date;
  • 結果
contract_dateuser_idstock_idstock_priceunitsdatestock_id_1closing_price
2022-10-211115011
2022-10-2211150212022-10-2111501
2022-10-2311150312022-10-2111501
2022-10-2311150312022-10-2211502
2022-10-2411150412022-10-2111501
2022-10-2411150412022-10-2211502
2022-10-2411150412022-10-2311503
2022-10-2511150512022-10-2111501
2022-10-2511150512022-10-2211502
2022-10-2511150512022-10-2311503
2022-10-2511150512022-10-2411504
~~~~~
  • 欲しい結果
    • これを「購入日時点における、最新の終値を持つ行」一つとだけ結合させたいのですが、いまいちやり方が分かりません。
contract_dateuser_idstock_idstock_priceunitsdatestock_id_1closing_price
2022-10-211115011
2022-10-2211150212022-10-2111501
2022-10-2311150312022-10-2211502
2022-10-2411150412022-10-2311503
2022-10-2511150512022-10-2411504
~~~~~

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

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

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

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

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

yambejp

2022/11/10 01:57

想定するSQLの種類とバージョンは?
Jonathan_Sf

2022/11/10 03:01

すみません。bigqueryですね。
yambejp

2022/11/10 05:08

BigQueryタグがあるのでつけてみるとよいかもしれません (逆にBigQuery専用の書き方を希望される場合はあまり多くの回答は期待できないかもしれませんが)
yambejp

2022/11/10 08:40

サンプルデータと、想定する結果も提示されると回答が付きやすくなると思います
Orlofsky

2022/11/10 09:34

質問は修正できます。 テーブル定義はCREATE TABLE文に、データはINSERT文に、現行のSELECT文とその結果、希望する結果結果も含めて Markdownの[コード]を使って提示してください。 https://teratail.com/help/question-tips#questionTips37
guest

回答1

0

OLAP版のSQLiteを目指しているというDuckDBの勉強中で,挑戦してみました。
プロから見ると変なコードと思いますが,こんな感じでどうでしょうか?

なお,DuckDBでは`テーブル名` が使えないので,
project.test.contractcontractproject.test.closing_priceclosing_price
で試しています。

sql

1WITH 2 all_data AS ( 3 SELECT 4 * 5 FROM `project.test.contract` 6 AS A LEFT JOIN 7 `project.test.closing_price` AS B 8 ON A.stock_id = B.stock_id AND A.contract_date > B.date 9 ORDER BY A.contract_date 10 ) , 11 rank_data AS ( 12 SELECT 13 * 14 , RANK() OVER(PARTITION BY contract_date, stock_id 15 ORDER BY date DESC) 16 AS rank FROM all_data 17 ) 18SELECT contract_date, user_id, stock_id, stock_price, 19 units, date, closing_price 20 FROM 21 rank_data 22 WHERE 23 rank=1 24 ; 25

一応結果です。stock_idがかぶっているので左側のみ残しています。

D .read test20230205-2.sql ┌───────────────┬─────────┬──────────┬─────────────┬───────┬────────────┬───────────────┐ │ contract_date │ user_id │ stock_id │ stock_price │ units │ date │ closing_price │ │ date │ int64 │ int64 │ int64 │ int64 │ date │ int64 │ ├───────────────┼─────────┼──────────┼─────────────┼───────┼────────────┼───────────────┤ │ 2022-10-21 │ 1 │ 1 │ 1501 │ 1 │ │ │ │ 2022-10-22 │ 1 │ 1 │ 1502 │ 1 │ 2022-10-21 │ 1501 │ │ 2022-10-23 │ 1 │ 1 │ 1503 │ 1 │ 2022-10-22 │ 1502 │ │ 2022-10-24 │ 1 │ 1 │ 1504 │ 1 │ 2022-10-23 │ 1503 │ │ 2022-10-25 │ 1 │ 1 │ 1505 │ 1 │ 2022-10-24 │ 1504 │ │ 2022-10-26 │ 1 │ 1 │ 1506 │ 1 │ 2022-10-25 │ 1505 │ │ 2022-10-27 │ 1 │ 1 │ 1507 │ 1 │ 2022-10-25 │ 1505 │ │ 2022-10-28 │ 1 │ 1 │ 1508 │ 1 │ 2022-10-25 │ 1505 │ │ 2022-10-29 │ 1 │ 1 │ 1509 │ 1 │ 2022-10-25 │ 1505 │ │ 2022-10-30 │ 1 │ 1 │ 1510 │ 1 │ 2022-10-25 │ 1505 │ ├───────────────┴─────────┴──────────┴─────────────┴───────┴────────────┴───────────────┤ │ 10 rows 7 columns │ └───────────────────────────────────────────────────────────────────────────────────────┘

投稿2023/02/05 14:11

ujimushi_sradjp

総合スコア2091

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問