mysql学习-having子句

1-4 having 子句

寻找缺失的编号

a) 进行升序或降序排序
b) 循环比较每一行和下一行的编号
—查询是否连续

/* 如果有查询结果,说明存在缺失的编号 */
SELECT '存在缺失的编号' AS gap
  FROM SeqTbl
HAVING COUNT(*) <> MAX(seq);

—查询缺失编号的最小值

/* 查询缺失编号的最小值 */
SELECT MIN(seq + 1) AS gap
  FROM SeqTbl
 WHERE (seq+ 1) NOT IN ( SELECT seq FROM SeqTbl);

用having子句进行子查询:求众数

–使用谓词

/* 求众数的SQL语句(1):使用谓词 */
  SELECT 
    income, COUNT(*) AS cnt
FROM
    Graduates
GROUP BY income
HAVING COUNT(*) >= ALL (SELECT 
        COUNT(*)
    FROM
        Graduates
    GROUP BY income)

—使用极值函数

/* 求众数的SQL语句(2):使用极值函数 */
SELECT 
    income, COUNT(*) AS cnt
FROM
    Graduates
GROUP BY income
HAVING COUNT(*) >= (SELECT 
        MAX(cnt)
    FROM
        (SELECT 
            COUNT(*) AS cnt
        FROM
            Graduates
        GROUP BY income) TMP);

用having子句进行子查询:求中位数

做法:将集合中元素按大小分为上半部分和下半部分两个子集,同时让这2个子集共同拥有集合正中间的元素,共同部分的元素的平均值即中位数

—使用非等值自连接

/* 求中位数的SQL语句:在HAVING子句中使用非等值自连接 */
SELECT 
    AVG(DISTINCT income)
FROM
    (SELECT 
        T1.income
    FROM
        Graduates T1, Graduates T2
    GROUP BY T1.income
    HAVING SUM(CASE
        WHEN T2.income >= T1.income THEN 1
        ELSE 0
    END) >= COUNT(*) / 2
        AND SUM(CASE
        WHEN T2.income <= T1.income THEN 1
        ELSE 0
    END) >= COUNT(*) / 2) TMP;

查询不包含NULL集合

count(*)和count(列名)区别:a.性能 b.count( *)可以用于null,而count(列名)与其他聚合函数一样,先排除null再统计。

/* 查询“提交日期”列内不包含NULL的学院(1):使用COUNT函数 */
SELECT 
    dpt
FROM
    Students
GROUP BY dpt
HAVING COUNT(*) = COUNT(sbmt_date);

—使用case表达式

/* 查询“提交日期”列内不包含NULL的学院(2):使用CASE表达式 */
SELECT 
    dpt
FROM
    Students
GROUP BY dpt
HAVING COUNT(*) = SUM(CASE
    WHEN sbmt_date IS NOT NULL THEN 1
    ELSE 0
END);

使用case表达式,将“提交日期”不是null的行记为1,否则记为0.这里case表达式相当于判断的函数,用来判断各个元素是否属于满足了某种条件的集合,这样的函数我们称为特征函数(或定义函数)

用关系除法运算进行购物篮分析

应用场景:查询同时服用多种药物的患者;查询UNIX和Oracle两者都精通的程序员等
HAVING子句:针对多行数据(或者说针对集合)设定查询条件
“带余除法”

/* 查询啤酒、纸尿裤和自行车同时在库的店铺 */
SELECT 
    SI.shop
FROM
    ShopItems SI,
    Items I
WHERE
    SI.item = I.item
GROUP BY SI.shop
HAVING COUNT(SI.item) = (SELECT 
        COUNT(item)
    FROM
        Items);

HAVING子句的子查询(SELECT COUNT(item) FROM Items) 的返回值是常量3。因此对商品表和店铺的库存管理表进行连接操作后结果是3行的店铺会被选中。

条件改变:"精准关系除法"即选择没有剩余商品的店铺
方法:外连接

/* 精确关系除法运算:使用外连接和COUNT函数 */
  SELECT 
    SI.shop
FROM
    ShopItems AS SI
        LEFT OUTER JOIN
    Items AS I ON SI.item = I.item
GROUP BY SI.shop
HAVING COUNT(SI.item) = (SELECT 
        COUNT(item)
    FROM
        Items)
    AND COUNT(I.item) = (SELECT 
        COUNT(item)
    FROM
        Items);  /* 条件2 */

条件1 排除count(SI.item)=4的仙台店 ;条件2 排除掉count(I.item)=2的大阪店
使用ShopItems作为主表

猜你喜欢

转载自blog.csdn.net/weixin_43387060/article/details/85956345