データのクエリ

このドキュメントでは、クエリジョブ、インタラクティブ クエリ、バッチクエリの実行など、BigQuery を使用してデータのクエリを行う方法について説明します。さらに、クエリをキャッシュする方法、サイズの大きいクエリ結果を返す方法、メタテーブルをクエリする方法についても記載しています。

クエリを実行する

クエリの結果は、一時テーブルまたは永続テーブルのいずれかに保存されます。既存のテーブルにデータを付加するか上書きするか、指定したテーブル名が存在しない場合に新しいテーブルを作成するかどうかを選択できます。

一時テーブルに書き込むクエリを実行するには、次のようにします。

ウェブ UI

  1. BigQuery ウェブ UI に移動します。BigQuery ウェブ UI に移動
  2. [Compose query] ボタンをクリックします。
  3. 有効な BigQuery SQL クエリを [New Query] テキスト領域に入力します。
  4. [Run query] ボタンをクリックします。

これにより、出力を一時テーブルに書き込むクエリジョブが作成されます。

コマンドライン

bq コマンドライン ツールを使用して、クエリを実行します。

API

API を使用してクエリを実行するには、新しいジョブを挿入して、jobs#configuration.query プロパティを設定します。

getQueryResults を呼び出して結果をポーリングし、jobCompletetrue になるまで継続します。その後エラーリストでエラーと警告を確認します。

C#

BigQuery クライアントのインストールと作成の詳細については、BigQuery クライアント ライブラリをご覧ください。

public BigQueryResults AsyncQuery(string projectId, string datasetId, string tableId,
    string query, BigQueryClient client)
{
    var table = client.GetTable(projectId, datasetId, tableId);
    BigQueryJob job = client.CreateQueryJob(query,
        new CreateQueryJobOptions { UseQueryCache = false });

    // Wait for the job to complete.
    job.PollUntilCompleted();

    // Then we can fetch the results, either via the job or by accessing
    // the destination table.
    return client.GetQueryResults(job.Reference.JobId);
}

Go

BigQuery クライアントのインストールと作成の詳細については、BigQuery クライアント ライブラリをご覧ください。

q := client.Query(fmt.Sprintf(`
	SELECT name, count
	FROM [%s.%s]
`, datasetID, tableID))
job, err := q.Run(ctx)
if err != nil {
	return err
}

// Wait until async querying is done.
status, err := job.Wait(ctx)
if err != nil {
	return err
}
if err := status.Err(); err != nil {
	return err
}

it, err := job.Read(ctx)
for {
	var row []bigquery.Value
	err := it.Next(&row)
	if err == iterator.Done {
		break
	}
	if err != nil {
		return err
	}
	fmt.Println(row)
}

Java

BigQuery クライアントのインストールと作成の詳細については、BigQuery クライアント ライブラリをご覧ください。

新しい QueryJobConfiguration を作成して BigQuery.create() 関数を使用し、クエリジョブを挿入します。

ジョブが完了したら、BigQuery.getQueryResults() を呼び出し、結果を確認します。

public static void runSimpleQuery(String queryString)
    throws TimeoutException, InterruptedException {
  QueryJobConfiguration queryConfig =
      QueryJobConfiguration.newBuilder(queryString).build();

  runQuery(queryConfig);
}
public static void runQuery(QueryJobConfiguration queryConfig)
    throws TimeoutException, InterruptedException {
  BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();

  // Create a job ID so that we can safely retry.
  JobId jobId = JobId.of(UUID.randomUUID().toString());
  Job queryJob = bigquery.create(JobInfo.newBuilder(queryConfig).setJobId(jobId).build());

  // Wait for the query to complete.
  queryJob = queryJob.waitFor();

  // Check for errors
  if (queryJob == null) {
    throw new RuntimeException("Job no longer exists");
  } else if (queryJob.getStatus().getError() != null) {
    // You can also look at queryJob.getStatus().getExecutionErrors() for all
    // errors, not just the latest one.
    throw new RuntimeException(queryJob.getStatus().getError().toString());
  }

  // Get the results.
  QueryResponse response = bigquery.getQueryResults(jobId);
  QueryResult result = response.getResult();

  // Print all pages of the results.
  while (result != null) {
    for (List<FieldValue> row : result.iterateAll()) {
      for (FieldValue val : row) {
        System.out.printf("%s,", val.toString());
      }
      System.out.printf("\n");
    }

    result = result.getNextPage();
  }
}

Node.js

BigQuery クライアントのインストールと作成の詳細については、BigQuery クライアント ライブラリをご覧ください。

// Imports the Google Cloud client library
const BigQuery = require('@google-cloud/bigquery');

// The project ID to use, e.g. "your-project-id"
// const projectId = "your-project-id";

// Instantiates a client
const bigquery = BigQuery({
  projectId: projectId
});

// Query options list: https://cloud.google.com/bigquery/docs/reference/v2/jobs/query
const options = {
  query: sqlQuery,
  useLegacySql: false // Use standard SQL syntax for queries.
};

let job;

// Runs the query as a job
bigquery
  .startQuery(options)
  .then((results) => {
    job = results[0];
    console.log(`Job ${job.id} started.`);
    return job.promise();
  })
  .then(() => {
    console.log(`Job ${job.id} completed.`);
    return job.getQueryResults();
  })
  .then((results) => {
    const rows = results[0];
    console.log('Rows:');
    rows.forEach((row) => console.log(row));
  })
  .catch((err) => {
    console.error('ERROR:', err);
  });

PHP

BigQuery クライアントのインストールと作成の詳細については、BigQuery クライアント ライブラリをご覧ください。

use Google\Cloud\BigQuery\BigQueryClient;
use Google\Cloud\Core\ExponentialBackoff;

/**
 * Run a BigQuery query as a job.
 * Example:
 * ```
 * $query = 'SELECT TOP(corpus, 10) as title, COUNT(*) as unique_words ' .
 *          'FROM [publicdata:samples.shakespeare]';
 * run_query_as_job($projectId, $query, true);
 * ```.
 *
 * @param string $projectId The Google project ID.
 * @param string $query     A SQL query to run. *
 * @param bool $useLegacySql Specifies whether to use BigQuery's legacy SQL
 *        syntax or standard SQL syntax for this query.
 */
function run_query_as_job($projectId, $query, $useLegacySql)
{
    $bigQuery = new BigQueryClient([
        'projectId' => $projectId,
    ]);
    $job = $bigQuery->runQueryAsJob(
        $query,
        ['jobConfig' => ['useLegacySql' => $useLegacySql]]);
    $backoff = new ExponentialBackoff(10);
    $backoff->execute(function () use ($job) {
        print('Waiting for job to complete' . PHP_EOL);
        $job->reload();
        if (!$job->isComplete()) {
            throw new Exception('Job has not yet completed', 500);
        }
    });
    $queryResults = $job->queryResults();

    if ($queryResults->isComplete()) {
        $i = 0;
        $rows = $queryResults->rows();
        foreach ($rows as $row) {
            printf('--- Row %s ---' . PHP_EOL, ++$i);
            foreach ($row as $column => $value) {
                printf('%s: %s' . PHP_EOL, $column, $value);
            }
        }
        printf('Found %s row(s)' . PHP_EOL, $i);
    } else {
        throw new Exception('The query failed to complete');
    }
}

Python

BigQuery クライアントのインストールと作成の詳細については、BigQuery クライアント ライブラリをご覧ください。

def async_query(query):
    client = bigquery.Client()
    query_job = client.run_async_query(str(uuid.uuid4()), query)
    query_job.use_legacy_sql = False
    query_job.begin()

    wait_for_job(query_job)

    # Drain the query results by requesting a page at a time.
    query_results = query_job.results()
    page_token = None

    while True:
        rows, total_rows, page_token = query_results.fetch_data(
            max_results=10,
            page_token=page_token)

        for row in rows:
            print(row)

        if not page_token:
            break
def wait_for_job(job):
    while True:
        job.reload()  # Refreshes the state via a GET request.
        if job.state == 'DONE':
            if job.error_result:
                raise RuntimeError(job.errors)
            return
        time.sleep(1)

Ruby

BigQuery クライアントのインストールと作成の詳細については、BigQuery クライアント ライブラリをご覧ください。

# project_id   = "your google cloud project id"
# query_string = "query string to execute (using bigquery query syntax)"

require "google/cloud/bigquery"

bigquery = Google::Cloud::Bigquery.new project: project_id

puts "Running query"
query_job = bigquery.query_job query_string

puts "Waiting for query to complete"
query_job.wait_until_done!

puts "Query results:"
query_job.query_results.each do |row|
  puts row.inspect
end

クエリの結果を永続テーブルに格納する

クエリの結果を永続テーブルに保存するには、次のようにします。

ウェブ UI

  1. BigQuery ウェブ UI に移動します。
    BigQuery ウェブ UI に移動

  2. [Compose query] ボタンをクリックします。

  3. 有効な BigQuery SQL クエリを [New Query] テキスト領域に入力します。

  4. [Show Options] ボタンをクリックします。

  5. [Destination Table] セクションの [Select Table] ボタンをクリックします。

  6. テーブルの ID を入力し、[OK] をクリックします。

  7. [Run query] ボタンをクリックします。

これにより、出力を永続テーブルに書き込むクエリジョブが作成されます。

または、宛先テーブルを指定しないでクエリを実行した場合は、結果ウィンドウの [Save as Table] ボタンをクリックすることで、一時テーブルを永続テーブルにコピーできます。

コマンドライン

クエリ結果に基づいて永続テーブルを作成するには、--destination_table フラグを使用します。たとえば、次のクエリでは、mydataset データセットに happyhalloween という名前の永続テーブルが作成されます。

bq query --destination_table=mydataset.happyhalloween "SELECT name,number
    FROM [bigquery-public-data:usa_names.usa_1910_current]
    WHERE gender = 'M'
    ORDER BY number DESC
    LIMIT 6"

API

クエリの結果を永続テーブルに保存するには、jobs#configuration.query.destinationTable プロパティの値を指定します。

Java

BigQuery クライアントのインストールと作成の詳細については、BigQuery クライアント ライブラリをご覧ください。

クエリの結果を永続テーブルに保存するには、QueryJobConfiguration宛先テーブルに必要な TableId を設定します。

public static void runQueryPermanentTable(
    String queryString,
    String destinationDataset,
    String destinationTable,
    boolean allowLargeResults) throws TimeoutException, InterruptedException {
  QueryJobConfiguration queryConfig =
      QueryJobConfiguration.newBuilder(queryString)
          // Save the results of the query to a permanent table.
          // See: https://cloud.google.com/bigquery/querying-data#permanent-table
          .setDestinationTable(TableId.of(destinationDataset, destinationTable))
          // Allow results larger than the maximum response size.
          // If true, a destination table must be set.
          // See: https://cloud.google.com/bigquery/querying-data#large-results
          .setAllowLargeResults(allowLargeResults)
          .build();

  runQuery(queryConfig);
}
public static void runQuery(QueryJobConfiguration queryConfig)
    throws TimeoutException, InterruptedException {
  BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();

  // Create a job ID so that we can safely retry.
  JobId jobId = JobId.of(UUID.randomUUID().toString());
  Job queryJob = bigquery.create(JobInfo.newBuilder(queryConfig).setJobId(jobId).build());

  // Wait for the query to complete.
  queryJob = queryJob.waitFor();

  // Check for errors
  if (queryJob == null) {
    throw new RuntimeException("Job no longer exists");
  } else if (queryJob.getStatus().getError() != null) {
    // You can also look at queryJob.getStatus().getExecutionErrors() for all
    // errors, not just the latest one.
    throw new RuntimeException(queryJob.getStatus().getError().toString());
  }

  // Get the results.
  QueryResponse response = bigquery.getQueryResults(jobId);
  QueryResult result = response.getResult();

  // Print all pages of the results.
  while (result != null) {
    for (List<FieldValue> row : result.iterateAll()) {
      for (FieldValue val : row) {
        System.out.printf("%s,", val.toString());
      }
      System.out.printf("\n");
    }

    result = result.getNextPage();
  }
}

クエリの結果をビューに保存する

ビューの作成方法については、ビューを使用するをご覧ください。

パラメータ化されたクエリを実行する

BigQuery はクエリ パラメータをサポートしています。ユーザーの入力からクエリが作成される場合に、SQL インジェクションを防ぐことができます。この機能は、標準 SQL 構文でのみ利用可能です。

名前付きパラメータを指定するには、@param_name のように @ 文字の後に識別子を使用します。たとえば、次のクエリは、特定の Shakespeare コーパスで、指定した値以上の単語数を持つ語句をすべて検索します。

#standardSQL
SELECT
  word,
  word_count
FROM
  `bigquery-public-data.samples.shakespeare`
WHERE
  corpus = @corpus
  AND word_count >= @min_word_count
ORDER BY
  word_count DESC;

また、プレースホルダ値 ? を使用して、位置パラメータを指定します。1 つのクエリで位置パラメータまたは名前付きパラメータを使用できますが、両方を使用することはできません。

コマンドライン

--parameter を使用して、"name:type:value" の形式でパラメータの値を指定します。空の名前を使用すると、位置パラメータが生成されます。型を省略すると、STRING が使用されます。

標準 SQL 構文を指定するには、--parameter フラグと --use_legacy_sql=False フラグを使用する必要があります。

bq query --use_legacy_sql=False \
    --parameter=corpus::romeoandjuliet \
    --parameter=min_word_count:INT64:250 \
    'SELECT word, word_count
    FROM `bigquery-public-data.samples.shakespeare`
    WHERE corpus = @corpus
    AND word_count >= @min_word_count
    ORDER BY word_count DESC;'

API

名前付きパラメータを使用するには、jobs#configuration.query.parameterModeNAMED を設定します。

jobs#configuration.query.queryParameters[] にパラメータのリストを設定します。各パラメータの名前に、クエリで使用する @param_name を設定します。

useLegacySqlfalse を設定して、標準 SQL 構文を有効にします。

{
  "query": "SELECT word, word_count FROM `bigquery-public-data.samples.shakespeare` WHERE corpus = @corpus AND word_count >= @min_word_count ORDER BY word_count DESC;",
  "queryParameters": [
    {
      "parameterType": {
        "type": "STRING"
      },
      "parameterValue": {
        "value": "romeoandjuliet"
      },
      "name": "corpus"
    },
    {
      "parameterType": {
        "type": "INT64"
      },
      "parameterValue": {
        "value": "250"
      },
      "name": "min_word_count"
    }
  ],
  "useLegacySql": false,
  "parameterMode": "NAMED"
}

Google API Explorer で試してみましょう

位置パラメータを使用するには、jobs#configuration.query.parameterModePOSITIONAL を設定します。

Java

BigQuery クライアントのインストールと作成の詳細については、BigQuery クライアント ライブラリをご覧ください。

private static void runNamed(final String corpus, final long minWordCount)
    throws InterruptedException {
  BigQuery bigquery =
      new BigQueryOptions.DefaultBigqueryFactory().create(BigQueryOptions.getDefaultInstance());

  String queryString =
      "SELECT word, word_count\n"
          + "FROM `bigquery-public-data.samples.shakespeare`\n"
          + "WHERE corpus = @corpus\n"
          + "AND word_count >= @min_word_count\n"
          + "ORDER BY word_count DESC";
  QueryRequest queryRequest =
      QueryRequest.newBuilder(queryString)
          .addNamedParameter("corpus", QueryParameterValue.string(corpus))
          .addNamedParameter("min_word_count", QueryParameterValue.int64(minWordCount))
          // Standard SQL syntax is required for parameterized queries.
          // See: https://cloud.google.com/bigquery/sql-reference/
          .setUseLegacySql(false)
          .build();

  // Execute the query.
  QueryResponse response = bigquery.query(queryRequest);

  // Wait for the job to finish (if the query takes more than 10 seconds to complete).
  while (!response.jobCompleted()) {
    Thread.sleep(1000);
    response = bigquery.getQueryResults(response.getJobId());
  }

  // Check for errors.
  if (response.hasErrors()) {
    String firstError = "";
    if (response.getExecutionErrors().size() != 0) {
      firstError = response.getExecutionErrors().get(0).getMessage();
    }
    throw new RuntimeException(firstError);
  }

  // Print all pages of the results.
  QueryResult result = response.getResult();
  while (result != null) {
    for (List<FieldValue> row : result.iterateAll()) {
      System.out.printf("%s: %d\n", row.get(0).getStringValue(), row.get(1).getLongValue());
    }

    result = result.getNextPage();
  }
}

Python

BigQuery クライアントのインストールと作成の詳細については、BigQuery クライアント ライブラリをご覧ください。

def wait_for_job(job):
    while True:
        job.reload()  # Refreshes the state via a GET request.
        if job.state == 'DONE':
            if job.error_result:
                raise RuntimeError(job.errors)
            return
        time.sleep(1)
def print_results(query_results):
    """Print the query results by requesting a page at a time."""
    page_token = None

    while True:
        rows, total_rows, page_token = query_results.fetch_data(
            max_results=10,
            page_token=page_token)

        for row in rows:
            print(row)

        if not page_token:
            break
def query_named_params(corpus, min_word_count):
    client = bigquery.Client()
    query = """
        SELECT word, word_count
        FROM `bigquery-public-data.samples.shakespeare`
        WHERE corpus = @corpus
        AND word_count >= @min_word_count
        ORDER BY word_count DESC;
        """
    query_job = client.run_async_query(
        str(uuid.uuid4()),
        query,
        query_parameters=(
            bigquery.ScalarQueryParameter('corpus', 'STRING', corpus),
            bigquery.ScalarQueryParameter(
                'min_word_count', 'INT64', min_word_count)))
    query_job.use_legacy_sql = False

    # Start the query and wait for the job to complete.
    query_job.begin()
    wait_for_job(query_job)
    print_results(query_job.results())

パラメータ化されたクエリで配列を使用する

クエリ パラメータで配列型を使用するには、型を ARRAY<T> に設定します。T は、配列内の要素の型です。[1, 2, 3] のように、要素をカンマで区切って角括弧で囲み、値を指定します。

配列型の詳細については、データ型のリファレンスをご覧ください。

コマンドライン

次のクエリは、米国で生まれた男の赤ちゃんに付けられた W で始まる名前の中で、最も多い名前を選択します。

bq query --use_legacy_sql=False \
    --parameter='gender::M' \
    --parameter='states:ARRAY<STRING>:["WA", "WI", "WV", "WY"]' \
    'SELECT name, sum(number) as count
    FROM `bigquery-public-data.usa_names.usa_1910_2013`
    WHERE gender = @gender
    AND state IN UNNEST(@states)
    GROUP BY name
    ORDER BY count DESC
    LIMIT 10;'

> 文字によってコマンドの出力がファイルにリダイレクトしないように、配列型の宣言を単一引用符で囲みます。

API

配列値を持つパラメータを使用するには、jobs#configuration.query.queryParameters[].parameterType.typeARRAY を設定します。

配列値がスカラーの場合には、jobs#configuration.query.queryParameters[].parameterType.arrayType.type に値の型(STRING など)を設定します。配列値が構造体の場合には、STRUCT に設定し、必要なフィールド定義を structTypes に追加します。

たとえば、次のクエリは、米国で生まれた男の赤ちゃんに付けられた W で始まる名前の中で、最も多い名前を選択します。

{
 "query": "SELECT name, sum(number) as count\nFROM `bigquery-public-data.usa_names.usa_1910_2013`\nWHERE gender = @gender\nAND state IN UNNEST(@states)\nGROUP BY name\nORDER BY count DESC\nLIMIT 10;",
 "queryParameters": [
  {
   "parameterType": {
    "type": "STRING"
   },
   "parameterValue": {
    "value": "M"
   },
   "name": "gender"
  },
  {
   "parameterType": {
    "type": "ARRAY",
    "arrayType": {
     "type": "STRING"
    }
   },
   "parameterValue": {
    "arrayValues": [
     {
      "value": "WA"
     },
     {
      "value": "WI"
     },
     {
      "value": "WV"
     },
     {
      "value": "WY"
     }
    ]
   },
   "name": "states"
  }
 ],
 "useLegacySql": false,
 "parameterMode": "NAMED"
}

Google API Explorer で試してみましょう

Java

BigQuery クライアントのインストールと作成の詳細については、BigQuery クライアント ライブラリをご覧ください。

private static void runArray(String gender, String[] states) throws InterruptedException {
  BigQuery bigquery =
      new BigQueryOptions.DefaultBigqueryFactory().create(BigQueryOptions.getDefaultInstance());

  String queryString =
      "SELECT name, sum(number) as count\n"
          + "FROM `bigquery-public-data.usa_names.usa_1910_2013`\n"
          + "WHERE gender = @gender\n"
          + "AND state IN UNNEST(@states)\n"
          + "GROUP BY name\n"
          + "ORDER BY count DESC\n"
          + "LIMIT 10;";
  QueryRequest queryRequest =
      QueryRequest.newBuilder(queryString)
          .addNamedParameter("gender", QueryParameterValue.string(gender))
          .addNamedParameter("states", QueryParameterValue.array(states, String.class))
          // Standard SQL syntax is required for parameterized queries.
          // See: https://cloud.google.com/bigquery/sql-reference/
          .setUseLegacySql(false)
          .build();

  // Execute the query.
  QueryResponse response = bigquery.query(queryRequest);

  // Wait for the job to finish (if the query takes more than 10 seconds to complete).
  while (!response.jobCompleted()) {
    Thread.sleep(1000);
    response = bigquery.getQueryResults(response.getJobId());
  }

  // Check for errors.
  if (response.hasErrors()) {
    String firstError = "";
    if (response.getExecutionErrors().size() != 0) {
      firstError = response.getExecutionErrors().get(0).getMessage();
    }
    throw new RuntimeException(firstError);
  }

  // Print all pages of the results.
  QueryResult result = response.getResult();
  while (result != null) {
    for (List<FieldValue> row : result.iterateAll()) {
      System.out.printf("%s: %d\n", row.get(0).getStringValue(), row.get(1).getLongValue());
    }

    result = result.getNextPage();
  }
}

Python

BigQuery クライアントのインストールと作成の詳細については、BigQuery クライアント ライブラリをご覧ください。

def wait_for_job(job):
    while True:
        job.reload()  # Refreshes the state via a GET request.
        if job.state == 'DONE':
            if job.error_result:
                raise RuntimeError(job.errors)
            return
        time.sleep(1)
def print_results(query_results):
    """Print the query results by requesting a page at a time."""
    page_token = None

    while True:
        rows, total_rows, page_token = query_results.fetch_data(
            max_results=10,
            page_token=page_token)

        for row in rows:
            print(row)

        if not page_token:
            break
def query_array_params(gender, states):
    client = bigquery.Client()
    query = """
        SELECT name, sum(number) as count
        FROM `bigquery-public-data.usa_names.usa_1910_2013`
        WHERE gender = @gender
        AND state IN UNNEST(@states)
        GROUP BY name
        ORDER BY count DESC
        LIMIT 10;
        """
    query_job = client.run_async_query(
        str(uuid.uuid4()),
        query,
        query_parameters=(
            bigquery.ScalarQueryParameter('gender', 'STRING', gender),
            bigquery.ArrayQueryParameter('states', 'STRING', states)))
    query_job.use_legacy_sql = False

    # Start the query and wait for the job to complete.
    query_job.begin()
    wait_for_job(query_job)
    print_results(query_job.results())

パラメータ化されたクエリでタイムスタンプを使用する

クエリ パラメータでタイムスタンプを使用するには、型を TIMESTAMP に設定します。値は、YYYY-MM-DD HH:MM:SS.DDDDDD time_zone の形式にします。

タイムスタンプ型の詳細については、データ型のリファレンスをご覧ください。

コマンドライン

次のクエリは、タイムスタンプ パラメータ値に時間を追加します。

bq query --use_legacy_sql=False \
    --parameter='ts_value:TIMESTAMP:2016-12-07 08:00:00' \
    'SELECT TIMESTAMP_ADD(@ts_value, INTERVAL 1 HOUR);'

API

タイムスタンプ パラメータを使用するには、jobs#configuration.query.queryParameters[].parameterType.typeTIMESTAMP を設定します。

次のクエリは、タイムスタンプ パラメータ値に時間を追加します。

{
  "query": "SELECT TIMESTAMP_ADD(@ts_value, INTERVAL 1 HOUR);",
  "queryParameters": [
    {
      "name": "ts_value",
      "parameterType": {
        "type": "TIMESTAMP"
      },
      "parameterValue": {
        "value": "2016-12-07 08:00:00"
      }
    }
  ],
  "useLegacySql": false,
  "parameterMode": "NAMED"
}

Google API Explorer で試してみましょう

Java

BigQuery クライアントのインストールと作成の詳細については、BigQuery クライアント ライブラリをご覧ください。

private static void runTimestamp() throws InterruptedException {
  BigQuery bigquery =
      new BigQueryOptions.DefaultBigqueryFactory().create(BigQueryOptions.getDefaultInstance());

  DateTime timestamp = new DateTime(2016, 12, 7, 8, 0, 0, DateTimeZone.UTC);

  String queryString = "SELECT TIMESTAMP_ADD(@ts_value, INTERVAL 1 HOUR);";
  QueryRequest queryRequest =
      QueryRequest.newBuilder(queryString)
          .addNamedParameter(
              "ts_value",
              QueryParameterValue.timestamp(
                  // Timestamp takes microseconds since 1970-01-01T00:00:00 UTC
                  timestamp.getMillis() * 1000))
          // Standard SQL syntax is required for parameterized queries.
          // See: https://cloud.google.com/bigquery/sql-reference/
          .setUseLegacySql(false)
          .build();

  // Execute the query.
  QueryResponse response = bigquery.query(queryRequest);

  // Wait for the job to finish (if the query takes more than 10 seconds to complete).
  while (!response.jobCompleted()) {
    Thread.sleep(1000);
    response = bigquery.getQueryResults(response.getJobId());
  }

  // Check for errors.
  if (response.hasErrors()) {
    String firstError = "";
    if (response.getExecutionErrors().size() != 0) {
      firstError = response.getExecutionErrors().get(0).getMessage();
    }
    throw new RuntimeException(firstError);
  }

  // Print all pages of the results.
  QueryResult result = response.getResult();
  DateTimeFormatter formatter = ISODateTimeFormat.dateTimeNoMillis().withZoneUTC();
  while (result != null) {
    for (List<FieldValue> row : result.iterateAll()) {
      System.out.printf(
          "%s\n",
          formatter.print(
              new DateTime(
                  // Timestamp values are returned in microseconds since 1970-01-01T00:00:00 UTC,
                  // but org.joda.time.DateTime constructor accepts times in milliseconds.
                  row.get(0).getTimestampValue() / 1000, DateTimeZone.UTC)));
    }

    result = result.getNextPage();
  }
}

Python

BigQuery クライアントのインストールと作成の詳細については、BigQuery クライアント ライブラリをご覧ください。

def wait_for_job(job):
    while True:
        job.reload()  # Refreshes the state via a GET request.
        if job.state == 'DONE':
            if job.error_result:
                raise RuntimeError(job.errors)
            return
        time.sleep(1)
def print_results(query_results):
    """Print the query results by requesting a page at a time."""
    page_token = None

    while True:
        rows, total_rows, page_token = query_results.fetch_data(
            max_results=10,
            page_token=page_token)

        for row in rows:
            print(row)

        if not page_token:
            break
def query_timestamp_params(year, month, day, hour, minute):
    client = bigquery.Client()
    query = 'SELECT TIMESTAMP_ADD(@ts_value, INTERVAL 1 HOUR);'
    query_job = client.run_async_query(
        str(uuid.uuid4()),
        query,
        query_parameters=[
            bigquery.ScalarQueryParameter(
                'ts_value',
                'TIMESTAMP',
                datetime.datetime(
                    year, month, day, hour, minute, tzinfo=pytz.UTC))])
    query_job.use_legacy_sql = False

    # Start the query and wait for the job to complete.
    query_job.begin()
    wait_for_job(query_job)
    print_results(query_job.results())

パラメータ化されたクエリで構造体を使用する

クエリ パラメータで構造体を使用するには、型を STRUCT<T> に設定します。T で構造体内のフィールドと型を定義します。フィールド定義はカンマで区切り、field_name TF という形式にします。TF はフィールドの型です。たとえば、STRUCT<x INT64, y STRING> では、最初のフィールドの型が INT64 で名前が x で、2 番目のフィールドの型が STRING で名前が y の構造体を定義しています。

構造体の型の詳細については、データ型のリファレンスをご覧ください。

コマンドライン

次の簡単なクエリでは、構造化型を使用してパラメータ値を返しています。

bq query --use_legacy_sql=False \
    --parameter='struct_value:STRUCT<x INT64, y STRING>:{"x": 1, "y": "foo"}' \
    'SELECT @struct_value AS s;'

API

構造体パラメータを使用するには、jobs#configuration.query.queryParameters.parameterType.typeSTRUCT を設定します。

構造体の各フィールドのオブジェクトを jobs#configuration.query.queryParameters.parameterType.structTypes に追加します。 構造体の値がスカラーの場合には、STRING のように type に値の型を設定します。構造体の値が配列の場合には、これを ARRAY に設定し、ネストされた arrayType フィールドに適切な型を設定します。値が構造体の場合、typeSTRUCT に設定して、必要な structTypes を追加します。

次の簡単なクエリでは、構造化型を使用してパラメータ値を返しています。

{
  "query": "SELECT @struct_value AS s;",
  "queryParameters": [
    {
      "name": "struct_value",
      "parameterType": {
        "type": "STRUCT",
        "structTypes": [
          {
            "name": "x",
            "type": {
              "type": "INT64"
            }
          },
          {
            "name": "y",
            "type": {
              "type": "STRING"
            }
          }
        ]
      },
      "parameterValue": {
        "structValues": {
          "x": {
            "value": "1"
          },
          "y": {
            "value": "foo"
          }
        }
      }
    }
  ],
  "useLegacySql": false,
  "parameterMode": "NAMED"
}

Google API Explorer で試してみましょう

Python

BigQuery クライアントのインストールと作成の詳細については、BigQuery クライアント ライブラリをご覧ください。

def wait_for_job(job):
    while True:
        job.reload()  # Refreshes the state via a GET request.
        if job.state == 'DONE':
            if job.error_result:
                raise RuntimeError(job.errors)
            return
        time.sleep(1)
def print_results(query_results):
    """Print the query results by requesting a page at a time."""
    page_token = None

    while True:
        rows, total_rows, page_token = query_results.fetch_data(
            max_results=10,
            page_token=page_token)

        for row in rows:
            print(row)

        if not page_token:
            break
def query_struct_params(x, y):
    client = bigquery.Client()
    query = 'SELECT @struct_value AS s;'
    query_job = client.run_async_query(
        str(uuid.uuid4()),
        query,
        query_parameters=[
            bigquery.StructQueryParameter(
                'struct_value',
                bigquery.ScalarQueryParameter('x', 'INT64', x),
                bigquery.ScalarQueryParameter('y', 'STRING', y))])
    query_job.use_legacy_sql = False

    # Start the query and wait for the job to complete.
    query_job.begin()
    wait_for_job(query_job)
    print_results(query_job.results())

インタラクティブ クエリまたはバッチクエリを実行する

デフォルトでは、BigQuery はインタラクティブ クエリを実行します。つまり、クエリはすぐに実行されます。インタラクティブ クエリは、同時実行のレート制限と毎日のレート制限に対してカウントされます。クエリを実行するのすべての例はインタラクティブ クエリです。

BigQuery ではバッチクエリも提供されています。BigQuery はユーザーに代わって各バッチクエリをキューに格納し、アイドル状態のリソースが使用可能になると(通常は数分以内)直ちにクエリを開始します。24 時間以内にクエリが開始されなかった場合、BigQuery はジョブの優先度をインタラクティブに変更します。バッチクエリは同時実行のレート制限に対してカウントされないので、簡単に多くのクエリを一度に開始できます。

バッチクエリを実行するには、次のようにします。

ウェブ UI

  1. BigQuery ウェブ UI に移動します。
    BigQuery ウェブ UI に移動

  2. [Compose query] ボタンをクリックします。

  3. 有効な BigQuery SQL クエリを [New Query] テキスト領域に入力します。

  4. [Show Options] ボタンをクリックします。

  5. [Query Priority] セクションで、[Batch] オプションを選択します。

  6. [Run query] ボタンをクリックします。

コマンドライン

バッチクエリを実行するには、--batch フラグを使用します。たとえば、次のクエリではバッチクエリを開始する方法を示します。

bq query --batch "SELECT name,number
    FROM [bigquery-public-data:usa_names.usa_1910_current]
    WHERE gender = 'M'
    ORDER BY number DESC
    LIMIT 6"

API

configuration.query.priority プロパティを指定し、値を BATCH に設定します。

Java

BigQuery クライアントのインストールと作成の詳細については、BigQuery クライアント ライブラリをご覧ください。

バッチクエリを実行するには、クエリの優先度QueryJobConfiguration.Priority.BATCH に設定します。この操作は、QueryJobConfiguration の作成時に行います。

public static void runBatchQuery(String queryString)
    throws TimeoutException, InterruptedException {
  QueryJobConfiguration queryConfig =
      QueryJobConfiguration.newBuilder(queryString)
          // Run at batch priority, which won't count toward concurrent rate
          // limit.
          // See: https://cloud.google.com/bigquery/querying-data#interactive-batch
          .setPriority(QueryJobConfiguration.Priority.BATCH)
          .build();

  runQuery(queryConfig);
}
public static void runQuery(QueryJobConfiguration queryConfig)
    throws TimeoutException, InterruptedException {
  BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();

  // Create a job ID so that we can safely retry.
  JobId jobId = JobId.of(UUID.randomUUID().toString());
  Job queryJob = bigquery.create(JobInfo.newBuilder(queryConfig).setJobId(jobId).build());

  // Wait for the query to complete.
  queryJob = queryJob.waitFor();

  // Check for errors
  if (queryJob == null) {
    throw new RuntimeException("Job no longer exists");
  } else if (queryJob.getStatus().getError() != null) {
    // You can also look at queryJob.getStatus().getExecutionErrors() for all
    // errors, not just the latest one.
    throw new RuntimeException(queryJob.getStatus().getError().toString());
  }

  // Get the results.
  QueryResponse response = bigquery.getQueryResults(jobId);
  QueryResult result = response.getResult();

  // Print all pages of the results.
  while (result != null) {
    for (List<FieldValue> row : result.iterateAll()) {
      for (FieldValue val : row) {
        System.out.printf("%s,", val.toString());
      }
      System.out.printf("\n");
    }

    result = result.getNextPage();
  }
}

キャッシュに保存されているクエリ結果を使用する

BigQuery はすべてのクエリ結果をテーブルに書き込みます。テーブルはユーザーが明示的に指定するか(宛先テーブル)、一時的なキャッシュ結果テーブルのいずれかです。一時的なキャッシュ結果テーブルは、ユーザー別、プロジェクト別に維持されます。

同じクエリを重複して実行すると、BigQuery はキャッシュに保存された結果を再利用しようとします。クエリ結果がキャッシュ結果テーブルから取得された場合、ジョブ統計プロパティ statistics.query.cacheHittrue が返され、そのクエリに対して課金されません。キャッシュに保存された結果を使用したクエリには課金されませんが、そのクエリは BigQuery の割り当てポリシーの対象になります。コスト削減に加えて、キャッシュに保存された結果を使用したクエリは BigQuery が結果セットを計算する必要がないため非常に高速です。

インタラクティブ クエリとバッチクエリの両方を含む、すべてのクエリ結果は一部の例外を除いて一時的なキャッシュ結果テーブルに約 24 時間保存されます。次の場合、クエリ結果はキャッシュに保存されません。

  • ジョブの設定、ウェブ UI、コマンドライン、または API で宛先テーブルが指定されている

  • 結果がキャッシュに保存された後で、参照するテーブルまたは論理ビューが変更された

  • クエリから参照されるいずれかのテーブルが、新しい行を受け取っていなくても、最近ストリーミング インサートを受信した(ストリーミング バッファがテーブルに添付された)

  • クエリが CURRENT_TIMESTAMP()NOW() といった日時関数などの変動関数を使用し、CURRENT_USER() など他の関数がクエリの実行タイミングによって異なる値を返す

  • キャッシュに保存された結果が期限切れとなった場合。通常、キャッシュのライフタイムは 24 時間ですが、キャッシュへの保存はベストエフォート式であり、すぐに無効になることがあります

クエリ結果がキャッシュ結果テーブルに存続するためには、結果セットを最大レスポンス サイズよりも小さくする必要があります。サイズの大きな結果セットの管理について詳しくは、大きいクエリ結果を返すをご覧ください。

キャッシュ結果テーブルの使用にはその他の制約があり、特殊なステータスがあります。キャッシュ結果テーブルは DML ステートメントのターゲットにできません。現在のセマンティックでは可能ですが、キャッシュに保存された結果を依存ジョブの入力として使用することは推奨されません。たとえば、キャッシュ テーブルから結果を取得するクエリジョブを送信しないでください。その代わりに、結果を名前付き宛先テーブルに書き込んでください。簡単にクリーンアップできるよう、データセット レベルの defaultTableExpirationMs プロパティなどの機能でデータを一定期間後に自動的に期限切れにすることができます。

キャッシュに保存されている結果の取得を無効にする

[Use cached results] オプションでは、クエリ対象のテーブルが変更された場合を除いて、以前に実行された同じクエリの結果が再利用されます。キャッシュされた結果の使用が役立つのは、クエリを繰り返し実行する場合のみです。新規のクエリでは [Use cached results] オプションの効果がありませんが、デフォルトで有効になっています。

[Use cached results] オプションを無効にしてクエリを繰り返し実行すると、既存のキャッシュされた結果が上書きされます。そのためには BigQuery でクエリ結果を計算する必要があり、そのクエリに対して課金されます。これは、ベンチマークのために非常に役立ちます。

キャッシュされた結果の取得を無効にし、クエリジョブの実行評価を強制的に行う場合は、クエリジョブの configuration.query.useQueryCache プロパティを false に設定します。

[Use cached results] オプションを無効にするには:

ウェブ UI

  1. BigQuery ウェブ UI に移動します。
    BigQuery ウェブ UI に移動

  2. [Compose query] ボタンをクリックします。

  3. 有効な BigQuery SQL クエリを [New Query] テキスト領域に入力します。

  4. [Show Options] をクリックします。

  5. [Use Cached Results] をオフにします。

コマンドライン

nouse_cache フラグを使用してクエリ キャッシュを上書きします。次の例では、BigQuery が既存のキャッシュされた結果を使用することなく、クエリを強制的に処理します。

 bq query --nouse_cache --batch "SELECT name,count FROM mydataset.names_2013 WHERE gender = 'M' ORDER BY count DESC LIMIT 6"

API

キャッシュに保存された結果を使用せずにクエリを処理するには、useQueryCache プロパティを false に設定します。

Java

BigQuery クライアントのインストールと作成の詳細については、BigQuery クライアント ライブラリをご覧ください。

キャッシュ内の結果を使用せずにクエリを処理するには、QueryJobConfiguration の作成時にクエリキャッシュの使用false に設定します。

public static void runUncachedQuery(String queryString)
    throws TimeoutException, InterruptedException {
  QueryJobConfiguration queryConfig =
      QueryJobConfiguration.newBuilder(queryString)
          // Do not use the query cache. Force live query evaluation.
          // See: https://cloud.google.com/bigquery/querying-data#query-caching
          .setUseQueryCache(false)
          .build();

  runQuery(queryConfig);
}
public static void runQuery(QueryJobConfiguration queryConfig)
    throws TimeoutException, InterruptedException {
  BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();

  // Create a job ID so that we can safely retry.
  JobId jobId = JobId.of(UUID.randomUUID().toString());
  Job queryJob = bigquery.create(JobInfo.newBuilder(queryConfig).setJobId(jobId).build());

  // Wait for the query to complete.
  queryJob = queryJob.waitFor();

  // Check for errors
  if (queryJob == null) {
    throw new RuntimeException("Job no longer exists");
  } else if (queryJob.getStatus().getError() != null) {
    // You can also look at queryJob.getStatus().getExecutionErrors() for all
    // errors, not just the latest one.
    throw new RuntimeException(queryJob.getStatus().getError().toString());
  }

  // Get the results.
  QueryResponse response = bigquery.getQueryResults(jobId);
  QueryResult result = response.getResult();

  // Print all pages of the results.
  while (result != null) {
    for (List<FieldValue> row : result.iterateAll()) {
      for (FieldValue val : row) {
        System.out.printf("%s,", val.toString());
      }
      System.out.printf("\n");
    }

    result = result.getNextPage();
  }
}

キャッシュを確実に使用する

jobs.insert() 関数を使用してクエリを実行する場合、ジョブ設定の createDisposition プロパティを CREATE_NEVER に設定すると、キャッシュの結果を使用できない場合にクエリジョブが強制的に失敗するようにできます。

キャッシュにクエリ結果が存在しない場合は、NOT_FOUND エラーが返されます。

キャッシュの使用を検証する

BigQuery がキャッシュを使用して結果を返したかどうかを判定するには 2 つの方法があります。

  • BigQuery ウェブ UI を使用した場合は、結果文字列に処理されたバイト数に関する情報が含まれず、「cached」と表示されます。

  • BigQuery API を使用した場合は、クエリ結果の cacheHit プロパティが true に設定されます。

大きいクエリ結果を返す

通常、クエリには最大レスポンス サイズがあります。それより大きい結果を返す可能性があるクエリを実行する場合は、ジョブの設定で allowLargeResultstrue に設定できます。大きい結果を設定する場合には、宛先テーブルを指定する必要があります。宛先テーブルにはストレージ料金が発生します。

大きい結果を返すクエリには次の制限が適用されます。

  • 宛先テーブルを指定する必要があります。
  • トップレベルの ORDER BYTOP または LIMIT 句を指定できません。指定した場合、クエリの出力を並列で計算できなくなるので、allowLargeResults を使用する利点がなくなります。
  • ウィンドウ関数は、PARTITION BY 句と組み合わせて使用した場合に限り、大きいクエリ結果を返すことができます。

大きなクエリ結果を許可するには:

ウェブ UI

  1. BigQuery ウェブ UI に移動します。
    BigQuery ウェブ UI に移動

  2. [Compose query] ボタンをクリックします。

  3. 有効な BigQuery SQL クエリを [New Query] テキスト領域に入力します。

  4. [Show Options] をクリックします。

  5. [Destination Table] で [Select Table] をクリックし、[Table ID] フィールドに名前を入力します。

  6. [Results Size] で [Allow Large Results] をオンにします。

コマンドライン

allow_large_results フラグと destination_table フラグを使用して、大きな結果を保存する宛先テーブルを作成します。

 bq query --destination_table '[DATASET].[TABLE_NAME]' --allow_large_results "[QUERY]"

API

大きな結果を有効にするには、configuration.query.allowLargeResults プロパティに true を設定し、configuration.query.destinationTable を使用して宛先テーブルを指定します。

Java

BigQuery クライアントのインストールと作成の詳細については、BigQuery クライアント ライブラリをご覧ください。

サイズの大きな結果を有効にするには、QueryJobConfiguration大容量の結果の許可true に設定し、宛先テーブルに必要な TableId を設定します。

public static void runQueryPermanentTable(
    String queryString,
    String destinationDataset,
    String destinationTable,
    boolean allowLargeResults) throws TimeoutException, InterruptedException {
  QueryJobConfiguration queryConfig =
      QueryJobConfiguration.newBuilder(queryString)
          // Save the results of the query to a permanent table.
          // See: https://cloud.google.com/bigquery/querying-data#permanent-table
          .setDestinationTable(TableId.of(destinationDataset, destinationTable))
          // Allow results larger than the maximum response size.
          // If true, a destination table must be set.
          // See: https://cloud.google.com/bigquery/querying-data#large-results
          .setAllowLargeResults(allowLargeResults)
          .build();

  runQuery(queryConfig);
}
public static void runQuery(QueryJobConfiguration queryConfig)
    throws TimeoutException, InterruptedException {
  BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();

  // Create a job ID so that we can safely retry.
  JobId jobId = JobId.of(UUID.randomUUID().toString());
  Job queryJob = bigquery.create(JobInfo.newBuilder(queryConfig).setJobId(jobId).build());

  // Wait for the query to complete.
  queryJob = queryJob.waitFor();

  // Check for errors
  if (queryJob == null) {
    throw new RuntimeException("Job no longer exists");
  } else if (queryJob.getStatus().getError() != null) {
    // You can also look at queryJob.getStatus().getExecutionErrors() for all
    // errors, not just the latest one.
    throw new RuntimeException(queryJob.getStatus().getError().toString());
  }

  // Get the results.
  QueryResponse response = bigquery.getQueryResults(jobId);
  QueryResult result = response.getResult();

  // Print all pages of the results.
  while (result != null) {
    for (List<FieldValue> row : result.iterateAll()) {
      for (FieldValue val : row) {
        System.out.printf("%s,", val.toString());
      }
      System.out.printf("\n");
    }

    result = result.getNextPage();
  }
}

テーブル デコレータを使用してテーブルのサブセットをクエリする

通常、BigQuery はクエリの実行時に列のフルスキャンを実行します。テーブル デコレータを使用すると、より効率的にデータのサブセットのクエリを実行できます。詳しくは、テーブル デコレータをご覧ください。

メタテーブルを使用する

BigQuery では、内容がメタデータ(テーブルの名前など)を表す特別なテーブルがいくつか提供されます。メタテーブルは読み取り専用です。通常、メタテーブルを使用するには SELECT ステートメントでメタテーブルを参照します。

メタテーブルは、クエリジョブだけでなく、tables.gettabledata.list などの他の API オペレーションでも使用できます。メタテーブルは tables.insert をサポートせず、宛先テーブルとしては使用できません。また、テーブル デコレータもサポートしていません。 メタテーブルは、データセットの tables.list には表示されません。

データセット内のテーブルに関するメタデータ

データセット内のテーブルに関するメタデータには、__TABLES__ または __TABLES_SUMMARY__ メタテーブルを使用してアクセスできます。

メタテーブルのクエリには次の構文を使用します。

    SELECT [FIELD] FROM [DATASET].__TABLES__;

DATASET はデータセットの名前で、FIELD は次のいずれかの値です。

フィールド 説明
project_id プロジェクトの名前。
dataset_id データセットの名前。
table_id テーブルの名前。
creation_time テーブルが作成された日時。UTC で 1970 年 1 月 1 日からのものをミリ秒単位で表示。
last_modified_time テーブルが最後に変更された日時。UTC で 1970 年 1 月 1 日からのものをミリ秒単位で表示。
row_count テーブル内の行数。
size_bytes バイト単位で測定されたテーブルの合計サイズ。
type テーブルの種類を表す整数。通常のテーブルは 1、ビューは 2。

次のクエリは、publicdata:samples データセット内のテーブルについてのメタデータを取得します。

    SELECT * FROM publicdata:samples.__TABLES__;

戻り値:

+------------+------------+-----------------+---------------+--------------------+-----------+--------------+------+
| project_id | dataset_id |    table_id     | creation_time | last_modified_time | row_count |  size_bytes  | type |
+------------+------------+-----------------+---------------+--------------------+-----------+--------------+------+
| publicdata | samples    | github_nested   | 1348782587310 |      1348782587310 |   2541639 |   1694950811 |    1 |
| publicdata | samples    | github_timeline | 1335915950690 |      1335915950690 |   6219749 |   3801936185 |    1 |
| publicdata | samples    | gsod            | 1335916040125 |      1440625349328 | 114420316 |  17290009238 |    1 |
| publicdata | samples    | natality        | 1335916045005 |      1440625330604 | 137826763 |  23562717384 |    1 |
| publicdata | samples    | shakespeare     | 1335916045099 |      1440625429551 |    164656 |      6432064 |    1 |
| publicdata | samples    | trigrams        | 1335916127449 |      1445684180324 |  68051509 | 277168458677 |    1 |
| publicdata | samples    | wikipedia       | 1335916132870 |      1445689914564 | 313797035 |  38324173849 |    1 |
+------------+------------+-----------------+---------------+--------------------+-----------+--------------+------+

多数のテーブルに拡張する

__TABLES__ では Tables.list より多くの情報が提供されますが、多数のテーブルを含むデータセットでは Tables.list の方が高速です。

__TABLES_SUMMARY__ はデータ依存フィールド last_modified_timerow_countsize_bytes を含まないので、__TABLES__ より処理速度が速いメタテーブルです。

一般に、最大数千個のテーブルを含むデータセットまでであれば、__TABLES____TABLES_SUMMARY__ は十分に高速です。それより大きいデータセットでは徐々に遅くなり、使用可能なリソースを超過する可能性があります。

一時テーブルと永続テーブル

BigQuery は、すべてのクエリ結果を永続テーブルまたは一時テーブルに保存できます。

  • 一時テーブルは、特殊なデータセットに保存された、ランダムな名前のテーブルです。このテーブルの有効期間は約 24 時間です。一時テーブルは共有できず、標準のリストや他のテーブル操作の方法を使用して表示することもできません。

  • 永続テーブルには、ユーザーが書き込み権限を持っている任意のデータセットの新しいテーブルまたは既存のテーブルを使用できます。

その他の制限

標準のクエリ割り当てに加えて、データのクエリには次の制限も適用されます。

  • クエリあたりの最大テーブル数: 1,000
  • 最大クエリ長: 256 KB
このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...

ご不明な点がありましたら、Google のサポートページをご覧ください。