forked from bojieli/ai-agent-book
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgold.py
More file actions
143 lines (131 loc) · 5.31 KB
/
Copy pathgold.py
File metadata and controls
143 lines (131 loc) · 5.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
"""
10 道题的「标准 SQL」(gold SQL),SQLite 方言,人工编写并逐题核对过。
用途:
- 离线演示(`python demo.py gold`):不调用任何 API,直接执行这些 SQL,
证明 schema + 种子数据这套数据模型本身是自洽、可查询的;
- 作为 Agent 生成 SQL 的「参考写法」:与 reference.py(纯 Python 参考实现)
语义一致,`demo.py` 会把执行结果与 reference.py 比对,逐题打印 通过/不通过。
约定:
- 日期一律用 date('now','localtime') / strftime(...,'now','localtime') 取「今天」,
与 seed.py 里以本地 date.today() 生成的数据对齐(避免 UTC 与本地相差一天);
- **不硬编码年份**,一律从数据库当前日期用修饰符推导('-1 year' / 'start of year' 等);
- 「A部门」= 研发部,「B部门」= 销售部;「在职」= leave_date IS NULL。
"""
GOLD = {
# 1. 平均每个员工在职多久(天)。离职用 leave_date,在职用今天。
1: """
SELECT ROUND(AVG(
julianday(COALESCE(leave_date, date('now','localtime')))
- julianday(hire_date)
), 2) AS avg_tenure_days
FROM employees;
""".strip(),
# 2. 每个部门有多少在职员工。
2: """
SELECT department, COUNT(*) AS active_count
FROM employees
WHERE leave_date IS NULL
GROUP BY department;
""".strip(),
# 3. 哪个部门(含离职)平均级别最高,只返回部门名。
3: """
SELECT department
FROM employees
GROUP BY department
ORDER BY AVG(level) DESC
LIMIT 1;
""".strip(),
# 4. 每个部门今年 / 去年各新入职多少人(按 hire_date 年份)。
4: """
SELECT department,
SUM(CASE WHEN strftime('%Y', hire_date)
= strftime('%Y','now','localtime') THEN 1 ELSE 0 END) AS this_year,
SUM(CASE WHEN strftime('%Y', hire_date)
= strftime('%Y','now','localtime','-1 year') THEN 1 ELSE 0 END) AS last_year
FROM employees
GROUP BY department
HAVING this_year > 0 OR last_year > 0;
""".strip(),
# 5. 前年3月 ~ 去年5月(含两端),研发部(A部门)平均工资。
5: """
SELECT ROUND(AVG(s.salary), 2) AS avg_salary
FROM salaries s
JOIN employees e ON e.emp_id = s.emp_id
WHERE e.department = '研发部'
AND strftime('%Y-%m', s.pay_date) BETWEEN
strftime('%Y-%m','now','localtime','start of year','-2 years','+2 months')
AND strftime('%Y-%m','now','localtime','start of year','-1 year','+4 months');
""".strip(),
# 6. 去年研发部(A)与销售部(B)平均工资,两行(含已离职员工)。
6: """
SELECT e.department, ROUND(AVG(s.salary), 2) AS avg_salary
FROM salaries s
JOIN employees e ON e.emp_id = s.emp_id
WHERE e.department IN ('研发部','销售部')
AND strftime('%Y', s.pay_date) = strftime('%Y','now','localtime','-1 year')
GROUP BY e.department;
""".strip(),
# 7. 今年每个级别的员工平均工资。
7: """
SELECT e.level, ROUND(AVG(s.salary), 2) AS avg_salary
FROM salaries s
JOIN employees e ON e.emp_id = s.emp_id
WHERE strftime('%Y', s.pay_date) = strftime('%Y','now','localtime')
GROUP BY e.level;
""".strip(),
# 8. 工龄分档(入职一年内 / 一到两年 / 两到三年,三年以上不计),各档最近一月工资的平均。
8: """
WITH latest AS ( -- 每位员工「最近一个月」的工资
SELECT s.emp_id, s.salary
FROM salaries s
JOIN (SELECT emp_id, MAX(pay_date) AS mp FROM salaries GROUP BY emp_id) m
ON m.emp_id = s.emp_id AND m.mp = s.pay_date
),
bucketed AS ( -- 给每位员工打上工龄档位
SELECT e.emp_id,
CASE
WHEN julianday(date('now','localtime')) - julianday(e.hire_date) < 365 THEN '入职一年内'
WHEN julianday(date('now','localtime')) - julianday(e.hire_date) < 730 THEN '一到两年'
WHEN julianday(date('now','localtime')) - julianday(e.hire_date) < 1095 THEN '两到三年'
ELSE NULL
END AS bucket
FROM employees e
)
SELECT b.bucket, ROUND(AVG(l.salary), 2) AS avg_salary
FROM bucketed b
JOIN latest l ON l.emp_id = b.emp_id
WHERE b.bucket IS NOT NULL
GROUP BY b.bucket;
""".strip(),
# 9. 去年到今年涨薪额(今年均薪 - 去年均薪)最大的 10 人,只算两年都有工资的。
9: """
WITH ty AS (
SELECT emp_id, AVG(salary) AS a FROM salaries
WHERE strftime('%Y', pay_date) = strftime('%Y','now','localtime') GROUP BY emp_id),
ly AS (
SELECT emp_id, AVG(salary) AS a FROM salaries
WHERE strftime('%Y', pay_date) = strftime('%Y','now','localtime','-1 year') GROUP BY emp_id)
SELECT e.name, ROUND(ty.a - ly.a, 2) AS raise_amt
FROM ty
JOIN ly ON ty.emp_id = ly.emp_id
JOIN employees e ON e.emp_id = ty.emp_id
ORDER BY raise_amt DESC
LIMIT 10;
""".strip(),
# 10. 拖欠工资:某月在职却没有发薪记录。递归展开每人的在职月份再左连接工资表。
10: """
WITH RECURSIVE em(emp_id, m, end_m) AS (
SELECT emp_id,
strftime('%Y-%m', hire_date),
COALESCE(strftime('%Y-%m', leave_date), strftime('%Y-%m','now','localtime'))
FROM employees
UNION ALL
SELECT emp_id, strftime('%Y-%m', date(m || '-01', '+1 month')), end_m
FROM em WHERE m < end_m)
SELECT em.emp_id, em.m
FROM em
LEFT JOIN salaries s
ON s.emp_id = em.emp_id AND strftime('%Y-%m', s.pay_date) = em.m
WHERE s.emp_id IS NULL;
""".strip(),
}