Apache Druid supports both SQL and native query APIs. Understanding both is crucial for flexible and optimized querying depending on your use case. In this post, we'll walk through how to run both SQL and native queries using curl, leveraging a sample sales dataset.
For example, I onboarded following sales_data to Druid.
sales_data.csv
timestamp,product,city,total_sales 2025-04-01T10:00:00Z,Laptop,Delhi,300 2025-04-01T10:00:00Z,Laptop,Delhi,200 2025-04-01T11:00:00Z,Tablet,Mumbai,150 2025-04-01T11:00:00Z,Tablet,Mumbai,50 2025-04-01T12:00:00Z,Mobile,Bengaluru,200 2025-04-01T13:00:00Z,Laptop,Hyderabad,250 2025-04-01T14:00:00Z,Tablet,Chennai,180 2025-04-01T15:00:00Z,Mobile,Pune,220 2025-04-01T15:00:00Z,Mobile,Pune,80
1. SQL Query via /druid/v2/sql
Druid’s SQL endpoint allows for familiar querying syntax:
Example SQL Query
Get total sales per product
SELECT product, SUM(total_sales) AS total_sales FROM sales_data GROUP BY product ORDER BY total_sales DESC
Execute Using curl
Save the following to a file sql_query.json.
sql_query.json
{
"query": "SELECT product, SUM(total_sales) AS total_sales FROM sales_data GROUP BY product ORDER BY total_sales DESC"
}
Run the query
curl -X POST http://localhost:8888/druid/v2/sql -H 'Content-Type:application/json' -d @sql_query.json
$curl -X POST http://localhost:8888/druid/v2/sql -H 'Content-Type:application/json' -d @sql_query.json
[{"product":"Laptop","total_sales":750.0},{"product":"Mobile","total_sales":500.0},{"product":"Tablet","total_sales":380.0}]
You can pass this curl output to jq command to pretty print.
$curl -X POST http://localhost:8888/druid/v2/sql -H 'Content-Type:application/json' -d @sql_query.json | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 246 100 125 100 121 9939 9621 --:--:-- --:--:-- --:--:-- 20500
[
{
"product": "Laptop",
"total_sales": 750.0
},
{
"product": "Mobile",
"total_sales": 500.0
},
{
"product": "Tablet",
"total_sales": 380.0
}
]
You can even pass the payload directly to druid/v2/sql API.
curl -X POST http://localhost:8888/druid/v2/sql -H 'Content-Type:application/json' -d '{"query":"SELECT product, SUM(total_sales) AS total_sales FROM sales_data GROUP BY product ORDER BY total_sales DESC"}'
$curl -X POST http://localhost:8888/druid/v2/sql -H 'Content-Type:application/json' -d '{"query":"SELECT product, SUM(total_sales) AS total_sales FROM sales_data GROUP BY product ORDER BY total_sales DESC"}' | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 243 100 125 100 118 9806 9257 --:--:-- --:--:-- --:--:-- 20250
[
{
"product": "Laptop",
"total_sales": 750.0
},
{
"product": "Mobile",
"total_sales": 500.0
},
{
"product": "Tablet",
"total_sales": 380.0
}
]
2. Native Query via /druid/v2
Native queries are powerful, fine-grained JSON-based constructs used for more complex operations.
Example Native Query
Equivalent native groupBy query for total sales per product:
Save to native_query.json.
Execute Using curl
native_query.json
{
"queryType": "groupBy",
"dataSource": "sales_data",
"granularity": "all",
"dimensions": ["product"],
"aggregations": [
{
"type": "longSum",
"name": "total_sales",
"fieldName": "total_sales"
}
],
"intervals": ["2025-04-01T00:00:00.000Z/2025-04-02T00:00:00.000Z"]
}
curl -X POST http://localhost:8888/druid/v2/?pretty -H 'Content-Type:application/json' -d @native_query.json
$curl -X POST http://localhost:8888/druid/v2/?pretty -H 'Content-Type:application/json' -d @native_query.json
[ {
"version" : "v1",
"timestamp" : "2025-04-01T00:00:00.000Z",
"event" : {
"product" : "Laptop",
"total_sales" : 750
}
}, {
"version" : "v1",
"timestamp" : "2025-04-01T00:00:00.000Z",
"event" : {
"product" : "Mobile",
"total_sales" : 500
}
}, {
"version" : "v1",
"timestamp" : "2025-04-01T00:00:00.000Z",
"event" : {
"product" : "Tablet",
"total_sales" : 380
}
} ]
Passing Native Query payload inline
curl -X POST http://localhost:8888/druid/v2/?pretty -H 'Content-Type:application/json' -d '{"queryType":"groupBy","dataSource":"sales_data","granularity":"all","dimensions":["product"],"aggregations":[{"type":"longSum","name":"total_sales","fieldName":"sales"}],"intervals":["2025-04-01T00:00:00.000Z/2025-04-02T00:00:00.000Z"]}'
$ curl -X POST http://localhost:8888/druid/v2/?pretty -H 'Content-Type:application/json' -d '{"queryType":"groupBy","dataSource":"sales_data","granularity":"all","dimensions":["product"],"aggregations":[{"type":"longSum","name":"total_sales","fieldName":"sales"}],"intervals":["2025-04-01T00:00:00.000Z/2025-04-02T00:00:00.000Z"]}'
[ {
"version" : "v1",
"timestamp" : "2025-04-01T00:00:00.000Z",
"event" : {
"product" : "Laptop",
"total_sales" : null
}
}, {
"version" : "v1",
"timestamp" : "2025-04-01T00:00:00.000Z",
"event" : {
"product" : "Mobile",
"total_sales" : null
}
}, {
"version" : "v1",
"timestamp" : "2025-04-01T00:00:00.000Z",
"event" : {
"product" : "Tablet",
"total_sales" : null
}
} ]
Previous Next Home


No comments:
Post a Comment