IT评测·应用市场-qidao123.com技术社区

标题: 读SQL进阶教程笔记05_关联子查询 [打印本页]

作者: 知者何南    时间: 2023-4-4 14:38
标题: 读SQL进阶教程笔记05_关联子查询

1. 关联子查询

1.1. 关联子查询和自连接在很多时候都是等价的
1.2. 使用SQL进行行间比较时,发挥主要作用的技术是关联子查询,特别是与自连接相结合的“自关联子查询”
1.3. 缺点
2. 增长、减少、维持现状

2.1. 使用基于时间序列的表进行时间序列分析
2.2. 示例
  1.    SELECT year, sale
  2.      FROM Sales S1
  3.     WHERE sale = (SELECT sale
  4.                    FROM Sales S2
  5.                    WHERE S2.year = S1.year -1)
  6.     ORDER BY year;
复制代码
  1.    SELECT S1.year, S1.sale
  2.      FROM Sales S1,
  3.          Sales S2
  4.     WHERE S2.sale = S1.sale
  5.      AND S2.year = S1.year -1
  6.     ORDER BY year;
复制代码
3. 用列表展示与上一年的比较结果

3.1. 示例
  1.    SELECT S1.year, S1.sale,
  2.          CASE WHEN sale =
  3.                (SELECT sale
  4.                    FROM Sales S2
  5.                  WHERE S2.year = S1.year -1) THEN'→'--持平
  6.                WHEN sale >
  7.                (SELECT sale
  8.                    FROM Sales S2
  9.                  WHERE S2.year = S1.year -1) THEN'↑'--增长
  10.                WHEN sale <
  11.                (SELECT sale
  12.                    FROM Sales S2
  13.                  WHERE S2.year = S1.year -1) THEN'↓'--减少
  14.          ELSE'—'END AS var
  15.      FROM Sales S1
  16.     ORDER BY year;
复制代码
  1.    SELECT S1.year, S1.sale,
  2.          CASE WHEN S1.sale = S2.sale THEN'→'
  3.                WHEN S1.sale > S2.sale THEN'↑'
  4.                WHEN S1.sale < S2.sale THEN'↓'
  5.          ELSE'—'END AS var
  6.      FROM Sales S1, Sales S2
  7.     WHERE S2.year = S1.year -1
  8.     ORDER BY year;
复制代码
4. 时间轴有间断时

4.1. 和过去最临近的时间进行比较
4.2. 示例
  1.    SELECT year, sale
  2.      FROM Sales2 S1
  3.     WHERE sale =
  4.      (SELECT sale
  5.          FROM Sales2 S2
  6.        WHERE S2.year =
  7.          (SELECT MAX(year)  --条件2:在满足条件1的年份中,年份最早的一个
  8.              FROM Sales2 S3
  9.            WHERE S1.year > S3.year))  --条件1:与该年份相比是过去的年份
  10.     ORDER BY year;
复制代码
  1. SELECT S1.year AS year,
  2.          S1.year AS year
  3.      FROM Sales2 S1, Sales2 S2
  4.     WHERE S1.sale = S2.sale
  5.      AND S2.year = (SELECT MAX(year)
  6.                        FROM Sales2 S3
  7.                      WHERE S1.year > S3.year)
  8.     ORDER BY year;
复制代码
  1.    SELECT S2.year AS pre_year,
  2.          S1.year AS now_year,
  3.          S2.sale AS pre_sale,
  4.          S1.sale AS now_sale,
  5.          S1.sale - S2.sale  AS diff
  6.      FROM Sales2 S1, Sales2 S2
  7.     WHERE S2.year = (SELECT MAX(year)
  8.                        FROM Sales2 S3
  9.                      WHERE S1.year > S3.year)
  10.     ORDER BY now_year;
复制代码
  1.    SELECT S2.year AS pre_year,
  2.          S1.year AS now_year,
  3.          S2.sale AS pre_sale,
  4.          S1.sale AS now_sale,
  5.          S1.sale - S2.sale  AS diff
  6.      FROM Sales2 S1, Sales2 S2
  7.     WHERE S2.year = (SELECT MAX(year)
  8.                        FROM Sales2 S3
  9.                      WHERE S1.year > S3.year)
  10.     ORDER BY now_year;
复制代码
5. 移动累计值和移动平均值

5.1. 示例
  1.    SELECT prc_date, prc_amt,
  2.          SUM(prc_amt) OVER (ORDER BY prc_date) AS onhand_amt
  3.      FROM Accounts;
复制代码
  1.    SELECT prc_date, A1.prc_amt,
  2.          (SELECT SUM(prc_amt)
  3.            FROM Accounts A2
  4.            WHERE A1.prc_date >= A2.prc_date ) AS onhand_amt
  5.      FROM Accounts A1
  6.     ORDER BY prc_date;
复制代码
  1.    SELECT prc_date, prc_amt,
  2.          SUM(prc_amt) OVER (ORDER BY prc_date
  3.                            ROWS 2 PRECEDING) AS onhand_amt
  4.      FROM Accounts;
复制代码
  1.    SELECT prc_date, A1.prc_amt,
  2.          (SELECT SUM(prc_amt)
  3.            FROM Accounts A2
  4.            WHERE A1.prc_date >= A2.prc_date
  5.              AND (SELECT COUNT(*)
  6.                    FROM Accounts A3
  7.                    WHERE A3.prc_date
  8.                      BETWEEN A2.prc_date AND A1.prc_date  ) <= 3 )
  9.                  AS mvg_sum
  10.      FROM Accounts A1
  11.     ORDER BY prc_date;
复制代码
  1.    SELECT prc_date, A1.prc_amt,
  2.     (SELECT SUM(prc_amt)
  3.        FROM Accounts A2
  4.      WHERE A1.prc_date >= A2.prc_date
  5.        AND (SELECT COUNT(*)
  6.                FROM Accounts A3
  7.              WHERE A3.prc_date
  8.                BETWEEN A2.prc_date AND A1.prc_date  ) <= 3
  9.      HAVING  COUNT(*) =3) AS mvg_sum  --不满3行数据的不显示
  10.      FROM Accounts A1
  11.     ORDER BY prc_date;
复制代码
5.2. 基本思路是使用冯·诺依曼型递归集合
6. 查询重叠的时间区间

6.1. 示例
  1.    SELECT reserver, start_date, end_date
  2.      FROM Reservations R1
  3.     WHERE EXISTS
  4.          (SELECT *
  5.                FROM Reservations R2
  6.               WHERE R1.reserver <> R2.reserver  --与自己以外的客人进行比较
  7.                 AND ( R1.start_date BETWEEN R2.start_date AND R2.end_date
  8.                                    --条件(1):自己的入住日期在他人的住宿期间内
  9.                    OR R1.end_date  BETWEEN R2.start_date AND R2.end_date));
  10.                                    --条件(2):自己的离店日期在他人的住宿期间内
复制代码
  1.    SELECT reserver, start_date, end_date
  2.     FROM Reservations R1
  3.    WHERE EXISTS
  4.          (SELECT *
  5.              FROM Reservations R2
  6.            WHERE R1.reserver <> R2.reserver
  7.              AND (  (     R1.start_date BETWEEN R2.start_date
  8.                                            AND R2.end_date
  9.                        OR R1.end_date   BETWEEN R2.start_date
  10.                                            AND R2.end_date)
  11.                    OR (    R2.start_date BETWEEN R1.start_date
  12.                                            AND R1.end_date
  13.                        AND R2.end_date   BETWEEN R1.start_date
  14.                                            AND R1.end_date)));
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 IT评测·应用市场-qidao123.com技术社区 (https://dis.qidao123.com/) Powered by Discuz! X3.4