
# SQL查询语法概述
SQL是用于访问和处理数据库的标准计算机语言。LTS SQL提供了查询日志流中结构化数据的语句, 以下均将 LTS SQL 称为 SQL。
SQL语言由用于处理数据库和数据库对象的命令和函数组成。使用该语言时需遵循有关表达式和文本使用的规则。因此在SQL参考章节，除了SQL语法参考外，还会看到有关表达式、函数和操作符等信息。SQL基本查询语句如下：
#### 约束与限制
此功能支持全部用户使用的局点有：华南-广州、华北-北京四、华北-乌兰察布一、华东-上海一、中国-香港、西南-贵阳一、亚太-新加坡、华北-北京一，支持部分白名单用户使用的局点有：华东-上海二、亚太-曼谷、华南-深圳、中东-利雅得、亚太-雅加达，其他局点暂不支持该功能。
#### 语法格式
```
SELECT [ ALL | DISTINCT ] { * | exprs } 
FROM { <subquery>} 
[ WHERE where_condition ] 
[ GROUP BY [ col_name_list ] 
[ HAVING expr ] 
[ ORDER BY expr [ ASC | DESC ], expr [ ASC | DESC ], ... ] 
[ LIMIT limit ] 
[ OFFSET offset ]
```
#### 数据类型
SQL查询中支持的数据类型如[表1]。如果当前字段数据类型需要改为其他数据类型，系统会进行数据类型的转换。例如STRING类型的字段转为LONG类型。字段数据类型转换之后的结果将会显示默认值，如STRING类型的数据转换为LONG类型的数据，结果会显示为LONG类型的默认值0。同理，当空值被转换为非空类型值时，也会使用默认值进行替换。例如，当把STRING类型空值转换为数字类型时，将会返回默认值0。
SQL语法中，字符必须被单引号（''）包裹，无符号或双引号（""）包裹的为字段或表名称，如：'msg'表示字符串msg，msg或"msg"表示日志结构化msg字段。
 表1SQL查询支持的数据类型 
| 原生数据类型 | 默认值 | 说明         |
|:---|:---|:---|
| STRING | ""  | 原生STRING类型 |
| FLOAT  | 0.0 | 原生FLOAT类型  |
| LONG   | 0   | 原生LONG类型   |
   
#### 查询语句
表2SQL查询语句 
| 语句       | 说明                                                                                                                                                             | 示例                                                                                                                                                                           |
|:---|:---|:---|
| DISTINCT | 返回去重后的结果。                                                                                                                                                      | SELECT DISTINCT visitCount                                                                                                                                                   |
| FROM     | 表示当前查询数据的源数据集， 可以是当前日志流的结构化数据, 也可以是当前日志流结构化数据的一个子集。 不加FROM的时候默认从当前日志流结构化数据查询，如果查询的数据源是一个子集， 则需要自己编写子查询语句。 | SELECT visitCount                                                                                                                                                            |
| WHERE    | 指定查询的过滤条件，支持算术运算符、关系运算符和逻辑运算符。具体过滤条件可填在where_condition处。                                                                                                       | SELECT visitCount WHERE visitCount \> 0                                                                                  |
| GROUP BY | 指定作为分组依据的结构化字段，支持根据单字段或多字段分组。具体的结构化字段列表可填入col_name_list处。                                                                                                      | SELECT host, count(\*) AS pv WHERE visitCount \> 0 GROUP BY host |
| HAVING   | 只能与GROUP BY配合使用。指定用于过滤GROUP BY结果的结构化字段。                                                                                                                        | SELECT host, count(\*) AS pv GROUP BY host HAVING pv \> 10         |
| ORDER BY | 后面的字段必须是用于GROUP BY分组的字段，对GROUP BY的查询结果进行排序，用于排序的可以是任意一个结构化字段。                                                                                                  | SELECT host, count(\*) AS pv GROUP BY host ORDER BY pv            |
| ASC/DESC | ASC为升序，DESC为降序，默认为ASC。                                                                                                                                         | SELECT host, count(\*) AS pv GROUP BY host ORDER BY pv DESC      |
| LIMIT    | 对查询结果进行限制，用于限制返回的结构化日志条数。一次查询最多返回100000条结构化日志。 如果不使用LIMIT语句，默认返回查询结果中最新的100条数据。                            | SELECT host LIMIT 100                                                                                                |
   
#### 示例
表3常用SQL查询语句示例 
| 查询需求                            | 查询语句                                                                    |
|:---|:---|
| 标准查询                            | SELECT "field" WHERE "field" = 'value'                                  |
| 统计行数                            | SELECT count(\*)                                                        |
| 列的别名                            | SELECT count(\*) AS "pv"                                                |
| 去重查询                            | SELECT DISTINCT("field")                                                |
| 分页查询                            | SELECT "field" LIMIT 100                                                |
| 排序查询                            | SELECT "__time" ORDER BY "__time"                                       |
| 分组查询                            | SELECT "field" GROUP BY "field"                                         |
| 分组统计                            | SELECT "field",count(\*) GROUP BY "field"                               |
| 模糊查询                            | SELECT "field" LIKE 'value%'                                            |
| 查询总和                            | SELECT sum("field")                                                     |
| 查询最大值                           | SELECT max("field")                                                     |
| 查询最小值                           | SELECT min("field")                                                     |
| 查询平均值                           | SELECT avg("field")                                                     |
| SQL嵌套子查询                        | SELECT sum(pv) FROM (SELECT "field",count(\*) AS "pv" GROUP BY "field") |
| HAVING子句过滤                      | SELECT "field",count(\*) AS "pv" GROUP BY "field" HAVING "pv" \> 10     |
| 查询包含GET，POST请求                  | SELECT \* WHERE "request_method" IN ('GET', 'POST')                     |
| 查询不包含GET，POST请求                 | SELECT \* WHERE "request_method" NOT IN ('GET', 'POST')                 |
| 查询非GET请求的日志                     | SELECT \* WHERE "request_method" != 'GET'                               |
| 查询GET请求成功并且状态码为200且请求时间小于60秒的日志 | SELECT \* WHERE "request_method" = 'GET' AND "request_time" \< 60       |
| 查询请求时间大于等于60秒，并且小于200秒的日志       | SELECT \* WHERE "request_ time" \>=60 and "request_time" \< 200         |
| 查询GET请求或POST请求的日志               | SELECT \* WHERE "request_method" = 'GET' OR "request_method" = 'POST'   |
   
下面的语句是根据ELB结构化日志构造出的查询语句， 它包含所有的基础查询语法， 仅供参考。
```
SELECT url AS Url, host AS Host, failure_rate AS FailureRate,
CONCAT(CAST(access_count AS varchar), ' times') AS "All",
CONCAT(CAST(rsp_200_count AS varchar), ' times') AS "COUNT_200"
FROM ( SELECT
CONCAT(host, CASE WHEN STRPOS(router_request_uri, '?') = 0 THEN router_request_uri ELSE SUBSTR(router_request_uri, 1, 1) END) AS url,
host,count(1) AS access_count,
SUM(CASE WHEN status = 200 THEN 1 ELSE 0 END) AS "rsp_200_count",
(CASE WHEN COUNT(1) < 30 THEN 0 ELSE round(SUM(CASE WHEN status >= 400 THEN 1 ELSE 0 END) * 100.0 / COUNT(1), 2) END) AS failure_rate
WHERE host NOT IN ('monitor-new.olayc.cn')
GROUP BY host,router_request_uri
HAVING router_request_uri NOT IN ('/robots.txt', '/null', '/undefined')
)
ORDER BY FailureRate DESC
LIMIT 100
```
