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