接続を始める
必要なのはGribStreamのAPIトークンと、MySQL互換のクライアントまたはライブラリだけです。
- 無料のAPIトークンを作成するか、既存のトークンを使います。
- ユーザー名には
gribstream、パスワードにはAPIトークンを指定します。 gfsなどのデータセットをデータベースとして選択し、接続します。
mysql --host=mysql.gribstream.com \
--port=3307 \
--user=gribstream \
--password \
--database=gfs \
--quick
MySQLコマンドラインクライアントではトークンの入力が求められるため、シェル履歴には残りません。このコマンドの--quickは、結果全体を待たず、到着した行から表示するための指定です。他のクライアントでは、結果を順次読み取る設定が異なります。
MySQLクエリはHTTP APIのクエリと同じAPIトークンとクォータを使います。使用量は、クエリに答えるために読み取った気象データに基づきます。データセット選びに迷った場合はモデルカタログを確認してください。全球データではgfsが分かりやすい出発点です。
MySQLを使う理由
MySQLドライバを備えた言語やツールなら、使い慣れた接続方法でGribStreamを検索できます。MySQLサーバーの運用、気象ファイルのインポート、新しいクライアントライブラリの習得は不要です。
この接続は読み取り専用で、気象データの検索に特化しています。データセットはデータベースとして表示され、気象フィールドを探索でき、未対応のSQLには明確なエラーが返ります。
気象列を探してクエリする
GribStreamの各気象パラメータは、データセット固有のMySQL列として公開されています。データセットを選んだら、クエリを書く前に利用できる列を確認してください。
SHOW FULL COLUMNS FROM gfs.timeseries;
結果から必要なFieldの値をコピーします。Commentには、読みやすい名称、元の単位、対応する正確なGS_VALUE(...)が表示されます。GFSの地上2 m気温なら、列名はtmp_2_m_above_groundです。
次の3つは同じ気象パラメータを表します。通常は気象列を使うのが最も簡単です。既存のHTTP APIクエリを変換するときやセレクタを動的に選ぶときは、正確なセレクタを指定できるGS_VALUEを使えます。JSON形式はモデルページに表示されるセレクタです。
tmp_2_m_above_ground
GS_VALUEによる正確な指定
GS_VALUE(
'TMP',
'2 m above ground',
''
)
{
"name": "TMP",
"level": "2 m above ground",
"info": ""
}
気象列名は自分で組み立てず、SHOW FULL COLUMNSまたはgribstream.selector_columnsからコピーしてください。多くは読みやすい名前ですが、長い名前や重複する名前には一定の規則で接尾辞が付きます。正確なセレクタ文字列では大文字と小文字が区別されます。
次のクエリは、1地点におけるGFSの地上2 m気温を今後6時間分返します。
SELECT forecasted_time,
tmp_2_m_above_ground AS temp_k
FROM gfs.timeseries
WHERE forecasted_time BETWEEN NOW() AND NOW() + INTERVAL 6 HOUR
AND lat = 40.758
AND lon = -73.985
AND lead_time BETWEEN '0h' AND '48h'
ORDER BY forecasted_time
LIMIT 100;
この気象列の値はケルビンで公開されています。列名や別名から推測せず、Commentまたはカタログで単位を確認してください。
結果は通常の行です。次の値は説明用の例です。
forecasted_time temp_k
2026-08-07 12:00:00 298.4
2026-08-07 13:00:00 299.1
2026-08-07 14:00:00 299.7
カタログで探す手順を使えば、パラメータ名から列を検索し、単位を確認し、必要に応じて正確なJSONセレクタやGS_VALUE式を取得できます。
接続時にgfsを選択済みならFROM timeseriesと書けます。未選択ならgfs.timeseriesのようにデータセットも指定します。
動作するクエリから始める
目的に最も近い例を開き、必要なデータセット、見つけた気象列、時刻、地点だけを変更してください。セレクタから列名を推測せず、SHOW FULL COLUMNSの列名をコピーします。
複数の名前付き地点を時間範囲で検索する
SELECT forecasted_time, name, lat, lon,
tmp_2_m_above_ground AS temp_k
FROM gfs.timeseries
WHERE forecasted_time BETWEEN '2026-07-13T00:00:00Z'
AND '2026-07-13T06:00:00Z'
AND (lat, lon, name) IN (
(40.758, -73.985, 'Times Square'),
(29.7604, -95.3698, 'Houston'),
(51.5072, -0.1276, 'London')
);
緯度・経度の規則的な格子を検索する
grid_stepを小さくすると選択する地点が増え、クォータ消費も増えます。まず粗い間隔で狭い領域を試してから、解像度を高めてください。
SELECT forecasted_time, lat, lon,
tmp_2_m_above_ground AS temp_k
FROM gfs.timeseries
WHERE forecasted_time BETWEEN '2026-07-13T00:00:00Z'
AND '2026-07-13T06:00:00Z'
AND lat BETWEEN 25 AND 50
AND lon BETWEEN -125 AND -66
AND grid_step = 1;
連続していない複数の有効時刻を正確に指定する
SELECT forecasted_time,
tmp_2_m_above_ground AS temp_k
FROM gfs.timeseries
WHERE forecasted_time IN (
'2026-07-13T00:00:00Z',
'2026-07-13T06:00:00Z',
'2026-07-14T18:00:00Z'
)
AND lat = 40.758
AND lon = -73.985;
特定のモデル実行による予報を検索する
SELECT forecasted_at, forecasted_time,
tmp_2_m_above_ground AS temp_k
FROM gfs.runs
WHERE forecasted_at BETWEEN '2026-07-13T00:00:00Z'
AND '2026-07-13T12:00:00Z'
AND lead_time BETWEEN '0h' AND '48h'
AND lat = 40.758
AND lon = -73.985
ORDER BY forecasted_at, forecasted_time;
過去の基準時刻より前に利用できた予報を再現する
SELECT forecasted_at, forecasted_time,
tmp_2_m_above_ground AS temp_k
FROM gfs.timeseries
WHERE forecasted_time BETWEEN '2026-07-13T00:00:00Z'
AND '2026-07-14T00:00:00Z'
AND forecasted_at <= '2026-07-12T18:00:00Z'
AND lat = 40.758
AND lon = -73.985
ORDER BY forecasted_time;
アンサンブルメンバーを選んで検索する
SELECT forecasted_time, member,
tmp_2_m_above_ground AS temp_k
FROM gefsatmos.timeseries
WHERE forecasted_time BETWEEN '2026-07-13T00:00:00Z'
AND '2026-07-13T12:00:00Z'
AND member IN (0, 1, 2)
AND lead_time BETWEEN '0h' AND '48h'
AND lat = 40.758
AND lon = -73.985;
値を変換し、しきい値を満たす行だけを残す
SELECT forecasted_time,
tmp_2_m_above_ground AS temp_k,
temp_k - 273.15 AS temp_c
FROM gfs.timeseries
WHERE forecasted_time BETWEEN '2026-07-13T00:00:00Z'
AND '2026-07-14T00:00:00Z'
AND lat = 40.758
AND lon = -73.985
AND temp_c BETWEEN 18 AND 24;
1つの有効時刻について最も暖かい格子点を探す
SELECT forecasted_time, lat, lon,
tmp_2_m_above_ground AS temp_k
FROM gfs.timeseries
WHERE forecasted_time = '2026-07-13T18:00:00Z'
AND lat BETWEEN 25 AND 50
AND lon BETWEEN -125 AND -66
AND grid_step = 0.5
ORDER BY temp_k DESC
LIMIT 20;
利用言語から接続する
以下から言語を選んでください。各例は安全に接続し、同じ小さな気象クエリを実行して行を読み取ります。トークンは環境変数またはシークレット管理サービスに保存し、接続文字列をコードに含めないでください。
MySQL 8コマンドラインクライアント。TLSは自動的にネゴシエーションされます。結果を順次表示するには--quickを追加します。
mysql \
-h mysql.gribstream.com -P 3307 \
-u gribstream -p -D gfs \
--quick
SQLAlchemyとpandasを介したConnector/Python。chunksizeを指定すると、結果全体を集めずDataFrameのイテレータを返します。
import os
import certifi
import pandas as pd
from sqlalchemy import URL, create_engine
url = URL.create(
"mysql+mysqlconnector",
username="gribstream",
password=os.environ["GRIBSTREAM_API_TOKEN"],
host="mysql.gribstream.com",
port=3307,
database="gfs",
)
engine = create_engine(url, connect_args={
"ssl_verify_cert": True,
"ssl_verify_identity": True,
"ssl_ca": certifi.where(),
})
sql = """
SELECT forecasted_time,
tmp_2_m_above_ground AS temp_k
FROM timeseries
WHERE forecasted_time BETWEEN NOW() AND NOW() + INTERVAL 6 HOUR
AND lat = 40.758 AND lon = -73.985
ORDER BY forecasted_time
"""
for frame in pd.read_sql_query(sql, engine, chunksize=10_000):
print(frame.head())
Connector/J。順次読み取るモードではフェッチサイズにInteger.MIN_VALUEを指定します。
String SQL = """
SELECT forecasted_time,
tmp_2_m_above_ground AS temp_k
FROM timeseries
WHERE forecasted_time BETWEEN NOW() AND NOW() + INTERVAL 6 HOUR
AND lat = 40.758 AND lon = -73.985
ORDER BY forecasted_time
""";
String url = "jdbc:mysql://mysql.gribstream.com:3307/gfs?sslMode=VERIFY_IDENTITY";
Properties props = new Properties();
props.setProperty("user", "gribstream");
props.setProperty("password", System.getenv("GRIBSTREAM_API_TOKEN"));
try (Connection db = DriverManager.getConnection(url, props);
Statement statement = db.createStatement(
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY)) {
statement.setFetchSize(Integer.MIN_VALUE);
try (ResultSet rows = statement.executeQuery(SQL)) {
while (rows.next()) {
System.out.println(rows.getTimestamp("forecasted_time"));
}
}
}
.NET向けのMySqlConnector。リーダーが行を順に読み取ります。
const string SQL = @"
SELECT forecasted_time,
tmp_2_m_above_ground AS temp_k
FROM timeseries
WHERE forecasted_time BETWEEN NOW() AND NOW() + INTERVAL 6 HOUR
AND lat = 40.758 AND lon = -73.985
ORDER BY forecasted_time";
var builder = new MySqlConnectionStringBuilder {
Server = "mysql.gribstream.com",
Port = 3307,
Database = "gfs",
UserID = "gribstream",
Password = Environment.GetEnvironmentVariable("GRIBSTREAM_API_TOKEN"),
SslMode = MySqlSslMode.VerifyFull,
};
await using var db = new MySqlConnection(builder.ConnectionString);
await db.OpenAsync();
await using var command = new MySqlCommand(SQL, db);
await using var rows = await command.ExecuteReaderAsync(
CommandBehavior.SequentialAccess);
while (await rows.ReadAsync()) {
Console.WriteLine(rows.GetDateTime("forecasted_time"));
}
go-sql-driver/mysql。Rows.Nextで反復すると、全行のスライスを作らずに結果を読み取れます。
const query = `
SELECT forecasted_time,
tmp_2_m_above_ground AS temp_k
FROM timeseries
WHERE forecasted_time BETWEEN NOW() AND NOW() + INTERVAL 6 HOUR
AND lat = 40.758 AND lon = -73.985
ORDER BY forecasted_time`
cfg := mysql.NewConfig()
cfg.User = "gribstream"
cfg.Passwd = os.Getenv("GRIBSTREAM_API_TOKEN")
cfg.Net = "tcp"
cfg.Addr = "mysql.gribstream.com:3307"
cfg.DBName = "gfs"
cfg.TLSConfig = "true"
cfg.ParseTime = true
db, err := sql.Open("mysql", cfg.FormatDSN())
if err != nil { log.Fatal(err) }
defer db.Close()
rows, err := db.QueryContext(ctx, query)
if err != nil { log.Fatal(err) }
defer rows.Close()
for rows.Next() {
var validTime time.Time
var tempK float64
if err := rows.Scan(&validTime, &tempK); err != nil { log.Fatal(err) }
}
mysql2のコールバックAPI。クエリストリームはNodeのバックプレッシャーに従います。
import mysql from 'mysql2';
const SQL = `
SELECT forecasted_time,
tmp_2_m_above_ground AS temp_k
FROM timeseries
WHERE forecasted_time BETWEEN NOW() AND NOW() + INTERVAL 6 HOUR
AND lat = 40.758 AND lon = -73.985
ORDER BY forecasted_time`;
const db = mysql.createConnection({
host: 'mysql.gribstream.com',
port: 3307,
user: 'gribstream',
password: process.env.GRIBSTREAM_API_TOKEN,
database: 'gfs',
ssl: {},
});
db.query(SQL)
.stream({ highWaterMark: 64 })
.on('data', row => console.log(row.forecasted_time))
.on('error', err => { throw err; })
.on('end', () => db.end());
Rustのmysqlクレート。query_iterはVecへ集約せず行を順次返します。
use mysql::{OptsBuilder, Pool, SslOpts};
use mysql::prelude::Queryable;
let sql = r#"
SELECT forecasted_time,
tmp_2_m_above_ground AS temp_k
FROM timeseries
WHERE forecasted_time BETWEEN NOW() AND NOW() + INTERVAL 6 HOUR
AND lat = 40.758 AND lon = -73.985
ORDER BY forecasted_time"#;
let opts = OptsBuilder::new()
.ip_or_hostname(Some("mysql.gribstream.com"))
.tcp_port(3307)
.user(Some("gribstream"))
.pass(std::env::var("GRIBSTREAM_API_TOKEN").ok())
.db_name(Some("gfs"))
.ssl_opts(Some(SslOpts::default()));
let pool = Pool::new(opts)?;
let mut db = pool.get_conn()?;
let rows = db.query_iter(sql)?;
for row in rows {
println!("{:?}", row?);
}
MySQL C API。mysql_use_resultで1行ずつ読み取ります。
const char *sql =
"SELECT forecasted_time, "
"tmp_2_m_above_ground AS temp_k "
"FROM timeseries "
"WHERE forecasted_time BETWEEN NOW() AND NOW() + INTERVAL 6 HOUR "
"AND lat = 40.758 AND lon = -73.985 "
"ORDER BY forecasted_time";
MYSQL *db = mysql_init(NULL);
unsigned int ssl_mode = SSL_MODE_VERIFY_IDENTITY;
mysql_options(db, MYSQL_OPT_SSL_MODE, &ssl_mode);
mysql_real_connect(db, "mysql.gribstream.com", "gribstream",
getenv("GRIBSTREAM_API_TOKEN"), "gfs", 3307, NULL, 0);
mysql_query(db, sql);
MYSQL_RES *result = mysql_use_result(db);
MYSQL_ROW row;
while ((row = mysql_fetch_row(result)) != NULL) {
printf("%s\n", row[0]);
}
mysql_free_result(result);
mysql_close(db);
1. GribStreamをアタッチする
DuckDBではMySQL拡張機能を使って接続をアタッチし、見つけた気象列をリモートテーブルとしてクエリできます。認証情報は標準のMYSQL_*環境変数へ設定し、読み取り専用でアタッチしてください。
export MYSQL_HOST=mysql.gribstream.com
export MYSQL_TCP_PORT=3307
export MYSQL_USER=gribstream
export MYSQL_PWD="$GRIBSTREAM_API_TOKEN"
export MYSQL_DATABASE=gfs
ATTACH 'ssl_mode=verify_identity' AS gribstream_db
(TYPE mysql, READ_ONLY);
2. 1地点または規則的なグリッドをクエリする
通常のアタッチ済みテーブルへのクエリで現在利用できる地点指定は、この例のような1地点、または緯度・経度の範囲とgrid_stepで定義する規則的なグリッドです。時刻、地点、リードタイムの条件はDuckDB側のクエリに残し、行が返される前にGribStreamへ渡せるようにします。
SELECT forecasted_time, lead_time, lat, lon,
tmp_2_m_above_ground AS temp_k
FROM gribstream_db.gfs.timeseries
WHERE forecasted_time BETWEEN CURRENT_TIMESTAMP
AND CURRENT_TIMESTAMP + INTERVAL 6 HOUR
AND lat = 40.758
AND lon = -73.985
AND lead_time BETWEEN 0 AND 48
LIMIT 100;
3. 生のクエリで複数地点を列挙する
離れた複数の座標を一度に指定するには、DuckDBのテーブル関数mysql_queryへ、GribStreamで利用できるSQL文を渡します。内側のSQL文はMySQL接続で直接実行されるため、GribStreamの座標タプル構文を利用できます。
SELECT *
FROM mysql_query('gribstream_db', $sql$
SELECT forecasted_time, name, lat, lon,
tmp_2_m_above_ground AS temp_k
FROM gfs.timeseries
WHERE forecasted_time BETWEEN NOW() AND NOW() + INTERVAL 6 HOUR
AND (lat, lon, name) IN (
(40.758, -73.985, 'Times Square'),
(29.7604, -95.3698, 'Houston')
)
AND lead_time BETWEEN '0h' AND '48h'
LIMIT 100
$sql$);
大きな結果には、ドライバの行イテレータ、ストリーミングモード、または同等の機能を使い、結果全体をメモリへ蓄積しないようにしてください。
timeseriesとrunsの選び方
各データセットのスキーマには、同じ2種類の気象テーブルがあります。返したい列ではなく、答えたい問いに合わせてテーブルを選びます。
timeseries
要求した各有効時刻について、条件を満たす最良の予報を取得するときに選びます。
絞り込みforecasted_time
runs
1つ以上の特定モデル実行による予報を調べるときに選びます。
絞り込みforecasted_atとlead_time
forecasted_atはモデル実行時刻、forecasted_timeは予報対象の有効時刻です。lead_timeは両者の差を時間単位で表し、結果列として選択することも条件に使うこともできます。
例:モデル実行の履歴を検索する
SELECT forecasted_at, forecasted_time, lat, lon,
tmp_2_m_above_ground AS temp_k
FROM gfs.runs
WHERE forecasted_at BETWEEN '2026-07-13T00:00:00Z'
AND '2026-07-13T12:00:00Z'
AND lead_time BETWEEN '0h' AND '48h'
AND lat = 40.758
AND lon = -73.985
ORDER BY forecasted_at DESC, forecasted_time ASC;
利用できる列、クエリ制御、更新情報
| 列 | 意味 | 注記 |
|---|---|---|
dataset | 行を生成したデータセットのコード | MySQLのスキーマ名でもあります |
forecasted_at | モデル実行時刻 | timeseriesでは、モデル実行の基準時刻に使える演算子は<=だけです |
forecasted_time | 予報対象の有効時刻 | timeseriesの主要な時刻列 |
lat, lon, name | 解決された地点と省略可能なラベル | nameはNULLになり得ます |
member | アンサンブルメンバーの識別子 | アンサンブルデータセットでのみ意味を持ちます |
index_updated_at | 行に関連付けられた配信元データの最新更新時刻 | 2つの予報時刻とは異なる、省略可能な更新メタデータ |
lead_time, grid_step | 予報のリードタイム(時間)と、指定したグリッド間隔(度) | 選択と絞り込みの両方に利用可能。地点を列挙した場合、grid_stepはNULL |
| データセット固有の気象列 | tmp_2_m_above_groundなどの元の気象値 | SHOW FULL COLUMNSで確認可能。値の型はDOUBLE |
各行に関連付けられた配信元データの最新更新時刻を見るにはindex_updated_atを選択します。これは更新情報であり、モデル実行時刻ではありません。モデル実行を識別するにはforecasted_atを使います。
SELECT forecasted_at, forecasted_time, index_updated_at,
tmp_2_m_above_ground AS temp_k
FROM gfs.timeseries
WHERE forecasted_time BETWEEN '2026-07-13T00:00:00Z'
AND '2026-07-13T06:00:00Z'
AND lat = 40.758
AND lon = -73.985
ORDER BY forecasted_time;
データセット、気象列、正確なセレクタを探す
列名、パラメータのレベル、単位を推測しないでください。データセットを見つけて気象列を確認し、API形式やGS_VALUEによる正確な指定が必要な場合だけセレクタの対応表を使います。
1. データセットを探す
SELECT code, full_name, provider, min_lead_time, max_lead_time,
is_ensemble, member_count, members, parameter_count
FROM gribstream.datasets
WHERE code LIKE '%gfs%'
ORDER BY code;
大規模な過去データの検索前に、アーカイブ範囲と更新間隔を確認する
SELECT code, archive_start, archive_window, rolling_window,
time_resolution, run_cadence, min_lead_time, max_lead_time,
catalog_updated_at
FROM gribstream.datasets
WHERE code = 'gfs';
archive_startとarchive_windowは公開されている収録範囲を表し、ローリング期間は時間とともに進みます。catalog_updated_atはカタログのメタデータ更新時刻です。行単位の更新情報が必要ならindex_updated_atを選択します。
2. 気象列を確認する
SHOW FULL COLUMNS FROM gfs.timeseries LIKE '%tmp%';
3. 対応表を検索するか、正確なセレクタを使う
SELECT short_name, full_name, units, has_code_table, variation_count
FROM gribstream.parameters
WHERE dataset = 'gfs'
AND (short_name = 'TMP' OR full_name LIKE '%temperature%')
ORDER BY short_name
LIMIT 20;
SELECT column_name, full_name, units, name, level, info,
selector_json, gs_value_sql
FROM gribstream.selector_columns
WHERE dataset = 'gfs'
AND column_name = 'tmp_2_m_above_ground';
gribstream.selector_columnsでは、各気象列に対応する読みやすい名称、単位、JSONセレクタ、同等のGS_VALUE式を確認できます。クエリにはdatasetの完全一致条件が必要です。
通常のSQLでは生成済みのcolumn_nameを使います。APIセレクタをそのままSQLへ置き換える場合はGS_VALUE(name, level, info)を使います。このgefsatmosmeanセレクタはinfoが空ではないため、3つすべての引数が必要です。
{
"name": "CAPE",
"level": "surface",
"info": "ens mean"
}
GS_VALUE(
'CAPE',
'surface',
'ens mean'
)
モデルページには引き続き標準のJSONセレクタと、対応する正確なGS_VALUE式が表示されます。SQL列名は、重複や長い識別子が解決済みの現在のスキーマからコピーしてください。
4. データセット間で比較できる気象要素を探す
共有パラメータには、共通の気象概念、出力単位、対応するデータセットが一覧表示されます。モデルを比較する前にこのカタログを使い、その後で各データセットの正確なセレクタを特定してください。セレクタ名が同じとは限りません。
SELECT code, label, units, supported_datasets
FROM gribstream.shared_parameters
WHERE code = 'temperature_2m';
例:地上10 mの風速を計算する
ifsoperの地上10 m風成分について正確なセレクタを見つけたら、func.Hypotで組み合わせます。
SELECT forecasted_time,
v_10u_sfc AS u_component,
v_10v_sfc AS v_component,
func.Hypot(u_component, v_component) AS wind_speed
FROM ifsoper.timeseries
WHERE forecasted_time BETWEEN '2026-07-13T00:00:00Z'
AND '2026-07-13T06:00:00Z'
AND lat = 48.8566
AND lon = 2.3522
ORDER BY forecasted_time;
機械可読な構文情報とMySQLの探索コマンド
接続先そのものからSQL構文と例を調べたいときに使います。
SELECT topic, supported_syntax, example, notes
FROM gribstream.sql_dialect
ORDER BY topic;
SELECT name, description, `sql`
FROM gribstream.query_examples
ORDER BY name;
SHOW TABLES、SHOW COLUMNS、DESCRIBE、SHOW CREATE TABLEなど、標準的なMySQLコマンドも利用できます。SHOW FULL COLUMNSには、簡潔な気象項目の説明と正確なGS_VALUE式も含まれます。
SHOW FULL COLUMNS FROM gfs.timeseries;
カタログテーブル
gribstream.datasetsgribstream.parametersgribstream.parameter_variationsgribstream.selector_columnsgribstream.shared_parametersgribstream.sql_dialectandgribstream.query_examples
メタデータのクエリでは、列の指定または*、DISTINCT、ORDER BY、非負のオフセットを伴うLIMIT、そして=、!=、LIKE、IN、NULL判定の範囲を限定した組み合わせを利用できます。
値、計算、フィルタ
計算列には一般的なSQL式を使い、SELECTリストの前方で定義した別名も参照できます。まず気象列に別名を付け、その別名を後続の式で使います。単位変換は明示的に記述してください。
SELECT forecasted_time,
tmp_2_m_above_ground AS temp_k,
temp_k - 273.15 AS temp_c
FROM gfs.timeseries
WHERE forecasted_time BETWEEN '2026-07-13T00:00:00Z'
AND '2026-07-13T12:00:00Z'
AND lat = 40.758
AND lon = -73.985
AND (temp_c BETWEEN 18 AND 30 OR temp_c IS NULL);
気象値の条件ではBETWEEN、数値のIN、NULL判定、括弧、NOT、ブール条件の組み合わせを利用できます。時刻、地点、リードタイム、メンバー、モデル実行の条件はANDで結び、ORは気象値の条件内だけで使います。
関数と複雑な計算
一般的な数値関数として、ABS、CEIL/CEILING、FLOOR、ROUND、SQRT、POW/POWER、MOD、TRUNCATEを利用できます。地点名にはLOWER/LCASE、UPPER/UCASE、TRIM、Unicode文字数を返すCHAR_LENGTHを使えます。MySQLのLENGTHはバイト数を返すため未対応です。地点名にはCHAR_LENGTHを使ってください。
SELECT forecasted_time,
ugrd_10_m_above_ground AS u,
vgrd_10_m_above_ground AS v,
func.Hypot(u, v) AS wind_speed
FROM gfs.timeseries
WHERE forecasted_time BETWEEN '2026-07-13T00:00:00Z'
AND '2026-07-13T12:00:00Z'
AND lat = 40.758
AND lon = -73.985
AND wind_speed > 5;
その他のGribStream式関数には明示的なfunc.名前空間を使います。式ではリテラル、括弧、単項演算子、算術演算、比較、ブール条件の組み合わせを利用できます。登録済みのfunc.呼び出しと引数は式のリファレンスを参照してください。
単位、データ型、欠損値
気象パラメータ列とGS_VALUEは、カタログに掲載された元の単位で値を返します。別名を付けても値は変換されません。コード化されたフィールドを連続量として扱う前に、gribstream.parametersのhas_code_tableを確認してください。
気象値、計算式、緯度、経度はMySQLのDOUBLEとして返ります。時刻列はDATETIME(6)、データセット、地点名、メンバー識別子は文字列です。欠損した数値や時刻はSQLのNULLになります。IS NULLまたはIS NOT NULLで判定してください。= NULLには対応していません。
プリペアドステートメント
通常のMySQLプレースホルダーを、セレクタ、計算、時刻、座標、メンバー、気象フィルタで使えます。相対時刻関数が評価されるのはプリペア時ではなく、ステートメントの実行時です。
SELECT forecasted_time AS valid_time,
GS_VALUE(?, ?) AS temp_k,
temp_k - ? AS temp_c
FROM gfs.timeseries
WHERE forecasted_time BETWEEN ? AND ?
AND lat = ?
AND lon = ?
AND temp_c BETWEEN ? AND ?
LIMIT 100;
件数を制限したDISTINCT結果
気象クエリではSELECT DISTINCT ... LIMIT nを利用できます。重複判定は選択した行全体に対して行われます。ORDER BYとは併用できず、新しい一意の行がないと判断するまで、範囲を限定した選択全体を読む場合があります。時刻や地点を絞る代わりではなく、範囲を限定した結果の重複除去に使ってください。
SELECT DISTINCT name,
tmp_2_m_above_ground AS temp_k
FROM gfs.timeseries
WHERE forecasted_time BETWEEN '2026-07-13T00:00:00Z'
AND '2026-07-13T06:00:00Z'
AND (lat, lon, name) IN (
(40.758, -73.985, 'Times Square'),
(29.7604, -95.3698, 'Houston')
)
LIMIT 100;
時間範囲、相対時刻、タイムゾーン
timeseries.forecasted_timeは有効時刻、runs.forecasted_atはモデル実行時刻です。範囲には両方の境界が必要で、BETWEENでは両端を含みます。
隣接する期間には、forecasted_time >= start AND forecasted_time < endのような半開区間を推奨します。連続したクエリを結合したとき、境界の時刻が重複しません。
SELECT forecasted_at, forecasted_time,
tmp_2_m_above_ground AS temp_k
FROM gfs.timeseries
WHERE forecasted_time BETWEEN NOW() - INTERVAL 2 DAY AND NOW()
AND forecasted_at <= NOW() - INTERVAL 6 HOUR
AND lat = 40.758
AND lon = -73.985
LIMIT 100;
対応する相対時刻関数とタイムスタンプ形式
NOW()、CURRENT_TIMESTAMP、UTC_TIMESTAMP()は、ステートメントごとにUTCで一度だけ評価されます。NOW(6)のような小数秒精度も指定できます。DATE_ADD、ADDDATE、DATE_SUB、SUBDATE、+ INTERVAL/- INTERVAL形式では、マイクロ秒から週までの固定長の整数単位を利用できます。長さが一定でない暦月と年は意図的に対象外です。
時刻リテラルには日付、MySQLの日時形式、Tを使うISO形式、UTCオフセット付きRFC 3339を指定できます。オフセットのない値は、CONVERT_TZへ入力する現地時刻を除き、UTCとして扱われます。
連続していない正確な時刻を指定する
1つの正確な時刻には=、連続していない複数の時刻にはINを使います。timeseriesではforecasted_time、runsではforecasted_atを指定します。完全な例はクエリ例にあります。
現地の暦日と夏時間を正しく扱う
SELECT forecasted_time,
CONVERT_TZ(forecasted_time, 'UTC', 'Europe/Paris') AS paris_time,
tmp_2_m_above_ground AS temp_k
FROM gfs.timeseries
WHERE forecasted_time >=
CONVERT_TZ('2026-10-25 00:00:00', 'Europe/Paris', 'UTC')
AND forecasted_time <
CONVERT_TZ('2026-10-26 00:00:00', 'Europe/Paris', 'UTC')
AND lat = 48.8566
AND lon = 2.3522
LIMIT 100;
IANAの名前付きタイムゾーンは夏時間の切り替えを考慮します。上のパリの範囲は、2026年10月25日の25時間ある秋の切り戻し日を含みます。同じ半開区間の書き方で、3月29日の23時間しかない春の切り替え日も正しく扱えます。入力された現地時刻は直ちにUTCへ変換され、曖昧または存在しない現地時刻には明確なエラーが返ります。結果側の変換ではforecasted_atとindex_updated_atも指定できます。秋の切り戻しで同じ現地時刻が2回表示される可能性がある場合は、元のUTC列も残してください。表示用に変換した時刻列の別名はWHEREでは使えません。
接続のタイムゾーンはUTCのままです。SET time_zoneにはUTC相当の値、SYSTEM、DEFAULTを指定できます。現地時刻が必要な場合はCONVERT_TZを使います。
過去のモデル実行時刻を上限にする
timeseriesでforecasted_at <= timestampを指定すると、それより新しいモデル実行を除外できます。timeseriesのこの列で使える演算子はこれだけです。データの更新状況を調べる場合はindex_updated_atを使います。完全な例はクエリ例にあります。
地点、格子、リードタイム、アンサンブル
1地点には1組の座標、複数の名前付き地点には座標の組のリスト、規則的な格子には緯度・経度の範囲とgrid_stepを使います。それぞれの完全な例はクエリ例にあります。
- 1地点:
lat = value AND lon = valueを使います。 - 複数地点:
(lat, lon)または(lat, lon, name)をINとともに使います。 - 格子:緯度と経度の両方を範囲指定し、度単位の
grid_stepを設定します。間隔を小さくすると地点数とクォータ消費が増えます。
リードタイムのフィルタ
lead_time = '24h'のように、時間を引用符で囲んで指定します。BETWEENは閉区間、対になった>=/<は半開区間、単独の比較は最小値または最大値だけを表します。時間の文字列には'90m'、'24h'、'168h'などを指定できます。
アンサンブルメンバーのフィルタ
メンバーを選ぶ前に、gribstream.datasetsのis_ensembleとmembers JSON配列を確認してください。すべてのデータセットがアンサンブルとは限らず、メンバー識別子の範囲も同じとは限りません。完全な例はクエリ例にあります。
効率のよいクエリにする
クォータ使用量は、返された行数ではなく、クエリの評価に読み取った気象データに基づきます。temp_c > 30のような気象値や計算済みの別名に対する条件は、その値を読み取った後でのみ結果から行を除外できます。そのため値のフィルタで返る行がごく少なくても、大きなクエリは多くのクォータを消費することがあります。
有効時刻、地点、リードタイム、アンサンブルメンバーの条件は、選択するデータ量を減らします。特に効果が大きいのは次の点です。
- 複数のモデル実行履歴が必要な場合を除き、
timeseriesを使います。 - 時間範囲を短くするか、正確な時刻のリストを使います。
- 必要な気象パラメータ列だけを選びます。
- 広い格子より正確な地点を優先し、格子を使う場合は適切な
grid_stepを選びます。 lead_timeを制限し、必要なアンサンブルメンバーだけを選びます。
探索時に並べ替えを使う
ORDER BYは主に対話的な操作やデータ探索向けです。多少の追加処理より、すぐに読める結果を優先するときに使います。範囲が限定されたクエリでは、主要な時刻列を最初のキーにすると、通常は行を順次返せます。timeseriesではforecasted_time、runsではforecasted_atを使い、昇順または降順を選びます。必要なら、選択した列や別名を第2キー以降に追加できます。
SELECT forecasted_time AS valid_time, name, lat, lon,
tmp_2_m_above_ground AS temp_k
FROM gfs.timeseries
WHERE forecasted_time BETWEEN '2026-07-13T00:00:00Z'
AND '2026-07-13T12:00:00Z'
AND (lat, lon, name) IN (
(40.758, -73.985, 'Times Square'),
(29.7604, -95.3698, 'Houston'),
(51.5072, -0.1276, 'London')
)
ORDER BY valid_time DESC, temp_k DESC, name ASC;
runsでは、forecasted_atを最初にし、lead_timeの両端を制限します。安全に処理できないほど大きな並べ替え結果になる場合は、選択範囲を狭めるかORDER BYを外し、アプリケーション側で並べ替えてください。
バックフィルなど大量のデータを取得するときはORDER BYを省略してください。順序が必要なら、受信後に並べ替えます。広い選択範囲と気象値のフィルタを組み合わせる場合は特に、サーバー側の並べ替えが処理速度の制約になるのを避けられます。
全体ランキング
気象値から始まる並べ替えは、行を返す前に選択範囲全体を確認する必要があるため、LIMITが必須です。順次出力ではなくランキングに使ってください。最も暖かい地点を探す完全な例はクエリ例にあります。
LIMITは結果の大きさに使い、クォータ制限には使わない
LIMITは対話的な出力を小さく保つのに便利ですが、読み取る気象データ量は決めません。フィルタや並べ替えでは、最終結果よりはるかに多くのデータを読むことがあります。クォータ使用量を減らすには、上記の選択条件を使ってください。
高度な機能:EXPLAINでクエリを検証
ほとんどのクエリにEXPLAINは必要ありません。気象クエリの先頭に付けると、気象データの行を取得せず、クエリのクォータも消費せずに、ステートメントを検証して診断情報を確認できます。主にトラブルシューティングやサポートで利用します。
EXPLAIN
SELECT forecasted_time, lat, lon,
tmp_2_m_above_ground AS temp_k
FROM gfs.timeseries
WHERE forecasted_time BETWEEN '2026-07-13T00:00:00Z'
AND '2026-07-13T12:00:00Z'
AND (lat, lon) = (40.758, -73.985)
LIMIT 100;
ストリーミング、キャンセル、エラー
行は順次利用可能になります。すぐに表示されるかどうかはMySQLクライアントやライブラリによるため、大きなクエリには非バッファ、ストリーミング、反復、または分割読み取りのインターフェースを使ってください。設定はクライアントごとに異なります。各ライブラリの資料はクライアントリファレンスから参照できます。
- クライアントの切断:接続を閉じると、実行中のクエリがキャンセルされます。
- MySQL CLI:Ctrl+Cで実行中のクエリを停止します。
アプリケーションからのキャンセルと同時実行
1つのMySQL接続で同時に実行できるステートメントは1つです。接続を再利用する前に結果を最後まで読むか閉じてください。本当にクエリの同時実行が必要なアプリケーションでは、接続プールを使います。プール内の各接続は個別に認証されます。
ドライバのキャンセルAPIまたはキャンセル可能なクエリコンテキストを使います。名称と動作はクライアントによって異なります。明示的にキャンセルするには、同じAPIトークンを使う別の接続からKILL QUERY <connection_id>を実行します。対象の接続はその後も再利用できます。
MySQLエラーコード
通常のMySQLエラーレスポンスを使うため、既存のクライアントが自然に表示できます。
| 状況 | MySQLコード | 表示される内容 |
|---|---|---|
| SQL構文 | 1064 | 未対応の入力付近を示す構文解析または検証エラー。 |
| 未対応のSQL | 1235 | 未対応の構文を具体的に説明します。 |
| 無効なトークン | 1045 | 接続認証時にアクセスが拒否されます。 |
| キャンセルされたクエリ | 1317 | クエリの実行が中断されました。 |
| レート制限 | 1226 | 利用可能な場合、再試行までの待ち時間がメッセージに表示されます。 |
トラブルシューティング
大きな結果の通信量を減らす
大量取得では、クライアントまたはドライバが対応していればMySQLプロトコルの圧縮を有効にしてください。設定方法はクライアントごとに異なります。付録の公式ドキュメントを参照してください。
MySQL CLI:接続時に--compression-algorithms=zstdを追加します。
どのクライアントからでも、次のクエリでネゴシエーションされた圧縮を確認できます。
SHOW SESSION STATUS LIKE 'Compression%';
TLS接続で証明書またはホスト名の検証に失敗する
IPアドレスではなくmysql.gribstream.comへ接続し、最新の信頼できるCA証明書ストアを使ってください。接続先の検証は有効のままにします。無効にすると、誤ったホスト名、通信の傍受、不完全な信頼ストアを見逃す可能性があります。信頼ストアと検証の設定はクライアントごとに異なります。クライアントリファレンスを参照してください。
接続がタイムアウトする
ネットワークからmysql.gribstream.comのポート3307へTCP接続を送信できることを確認してください。企業のファイアウォールや制限のあるノートブック環境では、標準以外のデータベースポートが遮断されることがあります。
気象列が見つからない、または正確なセレクタが拒否される
SHOW FULL COLUMNS FROM <dataset>.timeseriesを実行し、推測せずにFieldの値をコピーしてください。正確なセレクタをSQLで使う場合は、gribstream.selector_columnsからgs_value_sqlをコピーします。セレクタ文字列は大文字と小文字を区別し、翻訳や正規化は行いません。
値の大きさ、単位、意味が想定と異なる
GribStreamはセレクタに対応する元の値を返します。カタログのunits、description、has_code_tableを再確認し、正確なlevelとinfoを指定しているか確認してください。単位変換は明示的な計算列として記述します。ASで別名を付けるだけではデータは変わりません。
時間範囲、タイムゾーン、並べ替えクエリが拒否される
時間範囲の両端を指定してください。名前付きタイムゾーンの現地時刻の境界はCONVERT_TZでUTCへ変換します。夏時間の切り替えで曖昧または存在しない時刻を推測しないでください。安全に並べ替えられない場合は選択範囲を狭めるかORDER BYを外し、データを受け取るアプリケーションで並べ替えます。
クエリが終わるまで行が表示されない
クライアントが結果をバッファしています。非バッファ、ストリーミング、反復、または分割読み取りのモードを選んでください。MySQL CLI:--quickを付けて再接続します。pandas:chunksizeを指定します。その他のクライアントは付録の結果処理に関するドキュメントを参照してください。
クエリにMySQLエラー1226が返る
同時実行数を減らすか、エラーメッセージに表示された時間だけ待ってから再試行してください。すぐに繰り返し再試行すると、レート制限が長引くだけです。
AIエージェント向けの自己記述型ツールとして使う
MCPツールとして提供されるものを含め、汎用のMySQLデータベースコネクタからmysql.gribstream.com:3307へ接続できます。コネクタのシークレット設定を通じてAPIトークンを渡してください。
以下の手順ファイルをエージェントへ渡してください。スキーマとカタログテーブルから、データセット、気象列、単位、正確なセレクタの対応、SQL方言の規則、実行可能な例を調べてからクエリを組み立てられます。
gribstream.sql_dialectとgribstream.query_examplesを読みます。gribstream.datasetsを検索し、選んだ気象テーブルにSHOW FULL COLUMNSを実行します。- 正確なJSONセレクタまたは
GS_VALUEとの対応が必要な場合は、gribstream.selector_columnsを使います。 - 質問に答えられる、最小限で範囲の限られたクエリを組み立てて実行します。
EXPLAINはクエリの検証または問題調査にだけ使います。
完全な手順、構文の制限、データ取得のルールをまとめたGribStream MySQLエージェント向けスキルをダウンロードできます。
対応するSQLと意図的な制限
気象クエリ
timeseriesとrunsからのSELECT- 見つけた気象列と、
GS_VALUEによる正確な指定 - 計算列の別名、一般的な数値・文字列関数、ドキュメントに記載された
func.呼び出し - 時刻の範囲とリスト、地点、格子、メンバー、リードタイム
- 気象値に対するブールフィルタ
- 時刻を先頭にした並べ替え、または件数を制限した全体の上位N件
- 件数を制限した
DISTINCT、プリペアドステートメント、省略可能なEXPLAIN診断
意図的に未対応
- 書き込み、DDL、トランザクション、ロック
- 結合、サブクエリ、集約、グループ化
- 気象データの結果に対する
SELECT * - 無制限の全体並べ替えと並べ替え式
- 気象データ結果の0以外のオフセット
- 一覧にないMySQL関数と暗黙のSQL型変換
この制限により、意外な動作をするSQLを受け入れるのではなく、クエリの予測可能性、結果の順次読み取り、エラーの明確さを保ちます。
完全な互換性一覧
| 対象 | 対応する形式 | 制限 |
|---|---|---|
| セッション | USE、VERSION()、DATABASE()、UTC時刻関数、一般的なセッション変数と状態確認 | 互換性のための動作であり、MySQLサーバー変数の完全な集合ではありません |
| 探索 | SHOW DATABASES, SHOW TABLES, SHOW FULL COLUMNS, DESCRIBE, SHOW CREATE TABLE | GribStreamのスキーマとテーブルのみ |
| メタデータのSELECT | 列の指定または*、DISTINCT、ブールフィルタ、ORDER BY、LIMIT、非負のオフセット | カタログとinformation_schemaのテーブルのみ |
| 気象データのSELECT | 明示的な固定列と気象列、GS_VALUEによる指定、計算、範囲を限定した条件、フィルタ、制限付きDISTINCT | 気象データの*、結合、サブクエリ、グループ化、集約は未対応 |
| 並べ替え | 選択したキーは最大8個。時刻を先頭にした並べ替え、または件数を制限した全体の上位N件 | 式、列番号、重複キー、無制限の全体並べ替えは未対応 |
| プリペアドステートメント | セレクタ、式、時刻、地点、メンバー、フィルタで使える通常の?プレースホルダー | 1接続あたり最大5個のプリペアドステートメント |
| 高度な診断 | EXPLAIN SELECT ... | 実行せずに検証します。EXPLAIN ANALYZEには対応していません |
| キャンセル | 同じトークンを使う接続からKILL QUERY connection_id | 別のトークンの処理を確認またはキャンセルすることはできません |
付録:クライアント設定リファレンス
TLS、圧縮、結果のバッファリング、キャンセル、タイムアウト、接続プールはSQLではなくクライアントまたはドライバで設定します。実際に接続に使うライブラリのドキュメントを参照してください。
| クライアント | 公式ドキュメント | 確認できる内容 |
|---|---|---|
| MySQL CLI | クライアントオプションと接続オプション | TLS、圧縮、--quick、タイムアウト、その他のCLIオプション |
| Python | Connector/Pythonの接続引数とpandasのread_sql | TLS、圧縮、プール、接続オプション、DataFrameの分割読み取り |
| Java | Connector/Jの設定プロパティ | TLS、圧縮、タイムアウト、JDBCの動作 |
| C# / .NET | MySqlConnectorの接続オプション | TLS、圧縮、プール、タイムアウト |
| Go | go-sql-driver/mysqlのドキュメント | DSNオプション、TLS、圧縮、タイムアウト、プール |
| Node.js | mysql2のドキュメント | 接続、TLS、プール、プリペアドステートメント、結果のストリーミング |
| Rust | mysqlクレートのドキュメント | TLS、圧縮、プール、行の反復 |
| C | MySQL C APIガイド | 接続APIと結果API |
| DuckDB | DuckDB MySQL拡張機能 | 環境変数による認証情報、読み取り専用ATTACH、TLS、リモートテーブルのクエリ、mysql_query |
| DBeaver | MySQL接続設定とSSL設定 | MySQL 8接続、SSL、証明書の信頼設定、データベースナビゲーション |
