Skip to main content

Running SQL Statements

TDengine provides comprehensive support for SQL, allowing users to perform data queries, inserts, and deletions using familiar SQL syntax. TDengine's SQL also supports database and table management operations, such as creating, modifying, and deleting databases and tables. TDengine extends standard SQL by introducing features specific to time-series data processing, such as aggregation queries, downsampling, and interpolation queries, to accommodate the characteristics of time-series data. These extensions enable users to handle time-series data more efficiently and conduct complex data analysis and processing. For specific supported SQL syntax, please refer to TDengine SQL.

Below is an introduction to how to use various language connectors to execute SQL commands for creating databases, creating tables, inserting data, and querying data.

note

REST connection: Each programming language's connector encapsulates the connection using HTTP requests, supporting data writing and querying operations. Developers still access TDengine through the interfaces provided by the connector.
REST API: Directly calls the REST API interface provided by taosadapter to perform data writing and querying operations. Code examples demonstrate using the curl command.

Create Database and Table

Using a smart meter as an example, below demonstrates how to execute SQL commands using various language connectors to create a database named power and then set power as the default database. Next, it creates a supertable named meters, with columns including timestamp, current, voltage, phase, and tags for group ID and location.

try (Connection connection = DriverManager.getConnection(jdbcUrl, properties);
Statement stmt = connection.createStatement()) {

// create database
int rowsAffected = stmt.executeUpdate("CREATE DATABASE IF NOT EXISTS power");
// you can check rowsAffected here
System.out.println("Create database power successfully, rowsAffected: " + rowsAffected);
// create table
rowsAffected = stmt.executeUpdate("CREATE STABLE IF NOT EXISTS power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))");
// you can check rowsAffected here
System.out.println("Create stable power.meters successfully, rowsAffected: " + rowsAffected);
} catch (Exception ex) {
// please refer to the JDBC specifications for detailed exceptions info
System.out.printf("Failed to create database power or stable meters, %sErrMessage: %s%n",
ex instanceof SQLException ? "ErrCode: " + ((SQLException) ex).getErrorCode() + ", " : "",
ex.getMessage());
// Print stack trace for context in examples. Use logging in production.
ex.printStackTrace();
throw ex;
}

view source code

note

It is recommended to construct SQL statements using the <dbName>.<tableName> format; using the USE DBName approach in the application is not recommended.

Insert Data

Using a smart meter as an example, below demonstrates how to execute SQL to insert data into the meters supertable in the power database. The example uses TDengine's automatic table creation SQL syntax to write 3 data entries into the d1001 subtable and 1 data entry into the d1002 subtable, and then prints the actual number of inserted data entries.

// insert data, please make sure the database and table are created before
String insertQuery = "INSERT INTO " +
"power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " +
"VALUES " +
"(NOW + 1a, 10.30000, 219, 0.31000) " +
"(NOW + 2a, 12.60000, 218, 0.33000) " +
"(NOW + 3a, 12.30000, 221, 0.31000) " +
"power.d1002 USING power.meters TAGS(3, 'California.SanFrancisco') " +
"VALUES " +
"(NOW + 1a, 10.30000, 218, 0.25000) ";
try (Connection connection = DriverManager.getConnection(jdbcUrl, properties);
Statement stmt = connection.createStatement()) {

int affectedRows = stmt.executeUpdate(insertQuery);
// you can check affectedRows here
System.out.println("Successfully inserted " + affectedRows + " rows to power.meters.");
} catch (Exception ex) {
// please refer to the JDBC specifications for detailed exceptions info
System.out.printf("Failed to insert data to power.meters, sql: %s, %sErrMessage: %s%n",
insertQuery,
ex instanceof SQLException ? "ErrCode: " + ((SQLException) ex).getErrorCode() + ", " : "",
ex.getMessage());
// Print stack trace for context in examples. Use logging in production.
ex.printStackTrace();
throw ex;
}

view source code

note

NOW is an internal function that defaults to the current time of the client's computer. NOW + 1s means the client's current time plus 1 second; the number after represents the time unit: a (milliseconds), s (seconds), m (minutes), h (hours), d (days), w (weeks), n (months), y (years).

Query Data

Using a smart meter as an example, below demonstrates how to execute SQL using various language connectors to query data, retrieving up to 100 rows from the meters supertable in the power database and printing the results line by line.

String sql = "SELECT ts, current, location FROM power.meters limit 100";
try (Connection connection = DriverManager.getConnection(jdbcUrl, properties);
Statement stmt = connection.createStatement();
// query data, make sure the database and table are created before
ResultSet resultSet = stmt.executeQuery(sql)) {

Timestamp ts;
float current;
String location;
while (resultSet.next()) {
ts = resultSet.getTimestamp(1);
current = resultSet.getFloat(2);
// we recommend using the column name to get the value
location = resultSet.getString("location");

// you can check data here
System.out.printf("ts: %s, current: %f, location: %s %n", ts, current, location);
}
} catch (Exception ex) {
// please refer to the JDBC specifications for detailed exceptions info
System.out.printf("Failed to query data from power.meters, sql: %s, %sErrMessage: %s%n",
sql,
ex instanceof SQLException ? "ErrCode: " + ((SQLException) ex).getErrorCode() + ", " : "",
ex.getMessage());
// Print stack trace for context in examples. Use logging in production.
ex.printStackTrace();
throw ex;
}

view source code

note

Query operations are consistent with relational databases. When accessing return field content using indexes, start from 1; it is recommended to use field names for retrieval.

Execute SQL with reqId

reqId can be used for request tracing. It acts similarly to traceId in distributed systems. A request may need to go through multiple services or modules to complete. reqId is used to identify and associate all related operations for this request, making it easier to trace and analyze the complete path of the request.

Benefits of using reqId include:

  • Request tracing: By associating the same reqId with all related operations of a request, you can trace the complete path of the request within the system.
  • Performance analysis: Analyzing a request's reqId allows you to understand the processing time across various services and modules, helping to identify performance bottlenecks.
  • Fault diagnosis: When a request fails, you can find out where the issue occurred by examining the reqId associated with that request.

If users do not set a reqId, the connector will randomly generate one internally, but it is recommended to set it explicitly for better association with user requests.

Below are code samples for setting reqId while executing SQL with various language connectors.

long reqId = 3L;
try (Connection connection = DriverManager.getConnection(jdbcUrl, properties);
// Create a statement that allows specifying a request ID
AbstractStatement aStmt = (AbstractStatement) connection.createStatement()) {

try (ResultSet resultSet = aStmt.executeQuery("SELECT ts, current, location FROM power.meters limit 1", reqId)) {
Timestamp ts;
float current;
String location;
while (resultSet.next()) {
ts = resultSet.getTimestamp(1);
current = resultSet.getFloat(2);
// we recommend using the column name to get the value
location = resultSet.getString("location");

// you can check data here
System.out.printf("ts: %s, current: %f, location: %s %n", ts, current, location);

}
}
} catch (Exception ex) {
// please refer to the JDBC specifications for detailed exceptions info
System.out.printf("Failed to execute sql with reqId: %s, %sErrMessage: %s%n", reqId,
ex instanceof SQLException ? "ErrCode: " + ((SQLException) ex).getErrorCode() + ", " : "",
ex.getMessage());
// Print stack trace for context in examples. Use logging in production.
ex.printStackTrace();
throw ex;
}

view source code