単一テーブルからデータをクエリする
このドキュメントでは、SQLおよび各種プログラミング言語を使用して、データベース内の単一テーブルからデータを照会する方法について説明します。
始める前に
以下の内容は、TiDB の単一テーブルからデータをクエリする方法を示すために、 書店アプリケーションを例として使用します。
データを照会する前に、以下の手順を完了していることを確認してください。
簡単なクエリを実行します
Bookshopアプリケーションのデータベースでは、 authorsテーブルに著者の基本情報が格納されています。 SELECT ... FROM ...ステートメントを使用して、データベースからデータを照会できます。
MySQLクライアントで以下のSQL文を実行してください。
SELECT id, name FROM authors;
出力は以下のとおりです。
+------------+--------------------------+
| id | name |
+------------+--------------------------+
| 6357 | Adelle Bosco |
| 345397 | Chanelle Koepp |
| 807584 | Clementina Ryan |
| 839921 | Gage Huel |
| 850070 | Ray Armstrong |
| 850362 | Ford Waelchi |
| 881210 | Jayme Gutkowski |
| 1165261 | Allison Kuvalis |
| 1282036 | Adela Funk |
...
| 4294957408 | Lyla Nitzsche |
+------------+--------------------------+
20000 rows in set (0.05 sec)
Javaでは、著者の基本情報を格納するために、クラスAuthor価格帯データ型応じて適切なJavaデータ型を選択する必要があります。例:
Int型のデータを格納するには、int型の変数を使用します。Long型のデータを格納するには、bigint型の変数を使用します。Short型のデータを格納するには、tinyint型の変数を使用します。String型のデータを格納するには、varchar型の変数を使用します。
public class Author {
private Long id;
private String name;
private Short gender;
private Short birthYear;
private Short deathYear;
public Author() {}
// Skip the getters and setters.
}
public class AuthorDAO {
// Omit initialization of instance variables.
public List<Author> getAuthors() throws SQLException {
List<Author> authors = new ArrayList<>();
try (Connection conn = ds.getConnection()) {
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT id, name FROM authors");
while (rs.next()) {
Author author = new Author();
author.setId(rs.getLong("id"));
author.setName(rs.getString("name"));
authors.add(author);
}
}
return authors;
}
}
JDBCドライバを使用してTiDBに接続する後、 Statementを使用してconn.createStatement()オブジェクトを作成し、 stmt.executeQuery("query_sql")を呼び出して TiDB へのデータベース クエリ リクエストを開始できます。
クエリ結果はResultSetオブジェクトに格納されます。 ResultSetを走査することで、返された結果をAuthorオブジェクトにマッピングできます。
結果を絞り込む
クエリ結果をフィルタリングするには、 WHEREステートメントを使用できます。
例えば、以下のコマンドは、すべての著者の中から1998年生まれの著者を抽出します。
WHEREステートメントにフィルタ条件を追加します。
SELECT * FROM authors WHERE birth_year = 1998;
Javaでは、同じSQLを使用して、動的なパラメータを持つデータクエリ要求を処理できます。
これは、パラメータを SQL ステートメントに連結することで実行できます。ただし、この方法では、アプリケーションのセキュリティにSQLインジェクションインジェクションの潜在的なリスクが生じます。
このようなクエリに対処するには、通常のステートメントの代わりに準備された声明を使用します。
public List<Author> getAuthorsByBirthYear(Short birthYear) throws SQLException {
List<Author> authors = new ArrayList<>();
try (Connection conn = ds.getConnection()) {
PreparedStatement stmt = conn.prepareStatement("""
SELECT * FROM authors WHERE birth_year = ?;
""");
stmt.setShort(1, birthYear);
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
Author author = new Author();
author.setId(rs.getLong("id"));
author.setName(rs.getString("name"));
authors.add(author);
}
}
return authors;
}
結果を並べ替える
クエリ結果を並べ替えるには、 ORDER BYステートメントを使用できます。
例えば、次の SQL ステートメントは、 authorsテーブルを降順 ( DESC ) にソートすることにより、 birth_yearリストを取得します。
SELECT id, name, birth_year
FROM authors
ORDER BY birth_year DESC;
public List<Author> getAuthorsSortByBirthYear() throws SQLException {
List<Author> authors = new ArrayList<>();
try (Connection conn = ds.getConnection()) {
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("""
SELECT id, name, birth_year
FROM authors
ORDER BY birth_year DESC;
""");
while (rs.next()) {
Author author = new Author();
author.setId(rs.getLong("id"));
author.setName(rs.getString("name"));
author.setBirthYear(rs.getShort("birth_year"));
authors.add(author);
}
}
return authors;
}
結果は以下のとおりです。
+-----------+------------------------+------------+
| id | name | birth_year |
+-----------+------------------------+------------+
| 83420726 | Terrance Dach | 2000 |
| 57938667 | Margarita Christiansen | 2000 |
| 77441404 | Otto Dibbert | 2000 |
| 61338414 | Danial Cormier | 2000 |
| 49680887 | Alivia Lemke | 2000 |
| 45460101 | Itzel Cummings | 2000 |
| 38009380 | Percy Hodkiewicz | 2000 |
| 12943560 | Hulda Hackett | 2000 |
| 1294029 | Stanford Herman | 2000 |
| 111453184 | Jeffrey Brekke | 2000 |
...
300000 rows in set (0.23 sec)
クエリ結果の数を制限する
クエリ結果の数を制限するには、 LIMITステートメントを使用できます。
SELECT id, name, birth_year
FROM authors
ORDER BY birth_year DESC
LIMIT 10;
public List<Author> getAuthorsWithLimit(Integer limit) throws SQLException {
List<Author> authors = new ArrayList<>();
try (Connection conn = ds.getConnection()) {
PreparedStatement stmt = conn.prepareStatement("""
SELECT id, name, birth_year
FROM authors
ORDER BY birth_year DESC
LIMIT ?;
""");
stmt.setInt(1, limit);
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
Author author = new Author();
author.setId(rs.getLong("id"));
author.setName(rs.getString("name"));
author.setBirthYear(rs.getShort("birth_year"));
authors.add(author);
}
}
return authors;
}
結果は以下のとおりです。
+-----------+------------------------+------------+
| id | name | birth_year |
+-----------+------------------------+------------+
| 83420726 | Terrance Dach | 2000 |
| 57938667 | Margarita Christiansen | 2000 |
| 77441404 | Otto Dibbert | 2000 |
| 61338414 | Danial Cormier | 2000 |
| 49680887 | Alivia Lemke | 2000 |
| 45460101 | Itzel Cummings | 2000 |
| 38009380 | Percy Hodkiewicz | 2000 |
| 12943560 | Hulda Hackett | 2000 |
| 1294029 | Stanford Herman | 2000 |
| 111453184 | Jeffrey Brekke | 2000 |
+-----------+------------------------+------------+
10 rows in set (0.11 sec)
この例では、 LIMITステートメントを使用すると、クエリ時間が0.23 secから0.11 secに大幅に短縮されます。詳細については、 TopNとLimit参照してください。
集計クエリ
データの全体的な状況をよりよく理解するために、 GROUP BYステートメントを使用してクエリ結果を集計できます。
例えば、どの年に作家の出生数が多いかを知りたい場合は、 authorsテーブルをbirth_year列でグループ化し、各年ごとにカウントすることができます。
SELECT birth_year, COUNT (DISTINCT id) AS author_count
FROM authors
GROUP BY birth_year
ORDER BY author_count DESC;
public class AuthorCount {
private Short birthYear;
private Integer authorCount;
public AuthorCount() {}
// Skip the getters and setters.
}
public List<AuthorCount> getAuthorCountsByBirthYear() throws SQLException {
List<AuthorCount> authorCounts = new ArrayList<>();
try (Connection conn = ds.getConnection()) {
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("""
SELECT birth_year, COUNT(DISTINCT id) AS author_count
FROM authors
GROUP BY birth_year
ORDER BY author_count DESC;
""");
while (rs.next()) {
AuthorCount authorCount = new AuthorCount();
authorCount.setBirthYear(rs.getShort("birth_year"));
authorCount.setAuthorCount(rs.getInt("author_count"));
authorCounts.add(authorCount);
}
}
return authorCount;
}
結果は以下のとおりです。
+------------+--------------+
| birth_year | author_count |
+------------+--------------+
| 1932 | 317 |
| 1947 | 290 |
| 1939 | 282 |
| 1935 | 289 |
| 1968 | 291 |
| 1962 | 261 |
| 1961 | 283 |
| 1986 | 289 |
| 1994 | 280 |
...
| 1972 | 306 |
+------------+--------------+
71 rows in set (0.00 sec)
COUNT関数に加えて、TiDB は他の集計関数もサポートしています。詳細については、 集計(GROUP BY)関数参照してください。
お困りですか?
- 不和or スラックコミュニティに質問してください。
- TiDB Cloudのサポートチケットを送信してください
- TiDB Self-Managedのサポートチケットを送信してください