用oracle产生模拟数据表 workday: 记录了某企业 2020-01-01 到 2022-07-01(星期天) 的工作日情况,由 2 列组成,第一列 d 用于记录日期,记录方式为 char(10),例如‘2022-06-05’,记录是齐备的但未必排序。第二列为 w 用于记录是否工作日,是则记为 1,否则记为 0。
时间: 2024-02-03 07:13:35 浏览: 141
使用 Oracle 的 CONNECT BY LEVEL 和 DATE 函数可以快速生成 2020-01-01 到 2022-07-01 的所有日期,然后再根据工作日情况进行标记。
以下是一个示例 SQL:
```
CREATE TABLE workday (
d CHAR(10),
w NUMBER(1)
);
INSERT INTO workday (d, w)
SELECT TO_CHAR(dt, 'YYYY-MM-DD'), CASE TO_CHAR(dt, 'D') WHEN '1' THEN 0 ELSE 1 END
FROM (
SELECT TRUNC(TO_DATE('2020-01-01', 'YYYY-MM-DD')) + LEVEL - 1 AS dt
FROM DUAL
CONNECT BY LEVEL <= TRUNC(TO_DATE('2022-07-01', 'YYYY-MM-DD')) - TRUNC(TO_DATE('2020-01-01', 'YYYY-MM-DD')) + 1
);
COMMIT;
```
该 SQL 先使用 CONNECT BY LEVEL 和 DATE 函数生成了 2020-01-01 到 2022-07-01 的所有日期,然后根据每个日期是星期几进行标记,星期天为非工作日,其他为工作日。最后将结果插入到 workday 表中。
相关问题
用SQL自动产生模拟数据表 workday 记录了某企业 2020-01-01 到 2022-07-01(星期天)的工 作日情况,由 2 列组成,第一列 d 用于记录日期,记录方式为 char(10),例如‘2022-06-05’, 记录是齐备的但未必排序。第二列为 w 用于记录是否工作日,是则记为 1,否则记为 0。
可以使用 SQL 中的日期函数和随机函数来生成模拟数据。具体步骤如下:
1. 使用 generate_series 函数生成从 2020-01-01 到 2022-07-01 的日期序列。
2. 使用 date_part 函数和 extract 函数提取出每个日期的年、月、日和星期几信息。
3. 使用 case 函数和随机函数生成每个日期的工作日情况,如果是星期六或星期天,则记为非工作日(0),否则以一定概率记为工作日(1)。
4. 将生成的日期和工作日情况插入到 workday 表中。
具体 SQL 语句如下:
```
CREATE TABLE workday (
d CHAR(10),
w INTEGER
);
INSERT INTO workday (d, w)
SELECT to_char(dates, 'YYYY-MM-DD') AS d,
CASE WHEN extract(dow FROM dates) IN (0, 6) THEN 0
ELSE CASE WHEN random() < 0.8 THEN 1 ELSE 0 END
END AS w
FROM generate_series('2020-01-01'::date, '2022-07-01'::date, '1 day'::interval) AS dates;
```
其中,第一个查询使用 to_char 函数将日期转换为字符串格式,第二个查询使用 extract 函数提取日期的星期几信息,第三个查询使用 case 函数和 random 函数生成工作日情况,最后将生成的日期和工作日情况插入到 workday 表中。
自行产生模拟数据表 workday 记录了某企业 2020-01-01 到 2022-07-01(星期天)的工 作日情况,由 2 列组成,第一列 d 用于记录日期,记录方式为 char(10),例如‘2022-06-05’, 记录是齐备的但未必排序。第二列为 w 用于记录是否工作日,是则记为 1,否则记为 0。使 用分析函数求出该周期内最长的工作周(注意可能有多个),输出包括:工作周第一天,该 工作周包含的工作天数。
可以使用如下的 SQL 语句来求解该问题:
```
WITH RECURSIVE t (d, w, week_start, week_len, max_week_len) AS (
SELECT d, w, d, w, w FROM workday WHERE d = '2020-01-01'
UNION ALL
SELECT workday.d, workday.w,
CASE WHEN workday.w = 0 THEN workday.d ELSE t.week_start END,
CASE WHEN workday.w = 0 THEN 0 ELSE t.week_len + 1 END,
CASE WHEN workday.w = 0 THEN GREATEST(t.week_len, t.max_week_len) ELSE t.max_week_len END
FROM workday JOIN t ON workday.d = DATE(t.d, '+1 day')
WHERE workday.d <= '2022-07-01'
)
SELECT week_start, max_week_len
FROM t
WHERE week_len = max_week_len
```
这里使用了递归查询,首先从 `workday` 表中选择起始日期为 '2020-01-01' 的记录作为递归的起点,并初始化 `week_start`、`week_len` 和 `max_week_len` 均为该日期对应的值。然后,递归地向后遍历 `workday` 表中的日期,计算出每个日期所在的工作周的起始日期和包含的工作天数,并不断更新 `week_start`、`week_len` 和 `max_week_len` 的值。最终,从递归查询的结果中选择包含最多工作天数的工作周,输出该工作周的起始日期和工作天数即可。
阅读全文