testbook

过滤:WHERE子句和HAVING子句

查询中的一个常见操作是使用过滤来获得对用户有用的信息。过滤的条件可以通过WHERE子句或者HAVING子句指明。WHERE子句和HAVING子句的区别在于,一次查询中如果有WHERE子句,Inceptor会先执行WHERE子句的过滤条件再执行SELECT语句,而查询中如果用到了HAVING子句,Inceptor会先执行SELECT语句,再执行HAVING子句。换句话说,WHERE在SELECT之前过滤,而HAVING在SELECT之后过滤。

WHERE子句

举例

  • 单个过滤条件:下例从用户信息表中挑出所有在2010年之前注册的用户:
    [$host] transwarp> SELECT * FROM partition_user_info WHERE reg_date <20100000; 531547="" 841242="" 986634="" 3912384="" 4580952="" 5224133="" 20080214="" 20081031="" 20091202="" 魏向卉="" 522632199301029404="" 68537153578048="" a="" 宁新瑶="" 420822199001119507="" 97711008856576="" d="" 华微="" 420529198911075631="" 32638281095907="" b="" <="" pre="">
    
  • 含逻辑运算符的过滤条件:我们可以使用AND, OR和NOT来指定过滤条件。下例从用户信息表中挑出在2012年之前注册的A级或者B级用户:
    [$host] transwarp>  SELECT * FROM partition_user_info WHERE reg_date < 20120000 AND acc_level = 'A' OR acc_level = 'B';
    马从筠  6513065 115591  140400198711012307      96080357291141  20110101        A
    魏向卉  3912384 841242  522632199301029404      68537153578048  20091202        A
    华微    5224133 531547  420529198911075631      32638281095907  20080214        B
    
  • 用BETWEEN来表示带有范围的过滤条件:
    现在我们想要挑出在2010年和2012年之间注册的用户。我们可以使用AND语句来连接两个不等式:
    SELECT * FROM partition_user_info WHERE reg_date >20100000 AND reg_date <20120000; <="" pre="">
    也可以用BETWEEN来表示范围的区间:
    
    [$host] transwarp> SELECT * FROM partition_user_info WHERE reg_date BETWEEN 20100000 AND 20120000;
    李韩瑶  2755506 015859  310230197912126559      42412396242237  20110916        D
    马从筠  6513065 115591  140400198711012307      96080357291141  20110101        A
    祝韩恒  6670192 205239  230801197908126178      73790369990971  20100101        C
    潘营泽  6600641 990590  511521198705077435      48471135593608  20110430        C
    
  • 用IN来表示带有从属关系的过滤条件:
    有时候,过滤条件不是单个值,也不是一个区间中的值,而是一个有限集合。在这种情况下,我们可以用OR来连接这些过滤条件,也可以用IN来表示和过滤条件集合的从属关系:
    举例
    下例两个语句都可用来查询账户级别为A, B, C的账户持有人,两个语句的效果相同:
    [$host] transwarp> SELECT name FROM user_info WHERE acc_level = 'A' OR acc_level = 'B' OR acc_level = 'C';
    马从筠
    祝韩恒
    华微
    魏向卉
    邱坤
    潘营泽
    管淑艳
    
    [$host] transwarp> SELECT name FROM user_info WHERE acc_level IN ('A', 'B', 'C');
    马从筠
    祝韩恒
    华微
    魏向卉
    邱坤
    潘营泽
    管淑艳
    
    使用NOT IN可以表示过滤条件为不属于某个集合。下例查询账户级别不是A,B或C的账户持有人姓名:
    [$host] transwarp> SELECT name FROM user_info WHERE acc_level NOT IN ('A', 'B', 'C');
    宁新瑶
    李平
    李韩瑶
    
  • 在WHERE子句中嵌套子查询:
    举例
    下面语句通过对user_info和transactions两张表的查询查看在2014年第二季度有过交易的用户:
    [$host] transwarp> SELECT name FROM user_info WHERE acc_num IN (SELECT acc_num FROM transactions WHERE trans_time BETWEEN 20140401000000 AND 20140630235959);
    马从筠
    魏向卉
    邱坤
    
  • 使用HAVING子句

    举例 如果过滤条件受带GROUP BY的查询结果影响,那么就不能用WHERE子句来过滤,而要用HAVING子句。

    [$host] transwarp> SELECT acc\_num, max(price\*amount)
                     > FROM transactions
                     > WHERE trans\_time<'20140630235959'> GROUP BY acc_num
                     > HAVING max(price\*amount)>5000;
    6513065 12866.0
    5224133 8023.999999999999
    3912384 6843.000000000001
    0700735 5250.0