我有 2 个表:
1( et_pics - 此处有关员工的信息:
- ob_no、整数、键,例如 2020
- c_name,瓦尔查尔,例如运球手D.E.
-
e_post,瓦尔查尔,例如主席
从et_pics中选择 *:
ob_no | c_name | e_post
2020 |运球手 D.E. |主席
2( et_vacations – 此处存储有关假期的信息:
- ob_no,int,例如 666 e_pic,int,连接到pic.ob_no,例如 2020
- c_name,瓦尔查尔,例如假期等等等等
- e_dateFrom日期,例如 2010-08-08 00:00:00.000
-
e_dateTo,日期,例如 2010-08-09 00:00:00.000
从et_vacations VAC返回中选择*
ob_no | e_pic |c_name | e_dateFrom |e_dateTo
| 777 | 2020 |假期等等 |2010-08-08 00:00:00.000 |2010-08-09 00:00:00.000 |777 | 2020 |假期等等 |2015-08-08 00:00:00.000 |2015-08-09 00:00:00.000 |
我需要做的是将et_vacations连接到et_pics,条件是:
- 每人只能有一个假期记录(在我看来最大(e_dateTo((;
- 假期记录必须为>= getDate(( 或 null 为显示。
无法理解如何编写正确的子查询 – 尝试过这种方式,但没有运气:
SELECT
pics.c_name,
pics.e_post,
vac.e_dateTo
FROM et_pics pics
INNER JOIN et_division div on pics.e_division = div.ob_no
INNER JOIN et_vacations vac on vac.e_pic = pics.ob_no
WHERE
(pics.e_fireDate IS NULL OR pics.e_fireDate > getDate())
AND vac.e_dateTo IN (
SELECT MAX(vac.e_pic) from et_vacations vac
GROUP BY vac.e_pic
)
ORDER BY pics.c_name;
我相信你的问题需要围绕你感兴趣的假期日期(开始日期?,结束日期?(进行更多的定义,但这是一个开始。请注意,自从您拥有联接以来,我将连接留给了除法,但您没有在任何选择字段或 where 子句中使用该表中的数据。 除非它用于减少查询中的人数,因为不是et_pics中的每个人都在et_division,否则应删除此联接。
SELECT
pics.c_name,
pics.e_post,
vac.e_dateTo
FROM et_pics pics
INNER JOIN et_division div on pics.e_division = div.ob_no
INNER JOIN(select e_pic, max(e_dateTo) from et_vacations group by e_pic )vac on vac.e_pic = pics.ob_no
WHERE
(pics.e_fireDate IS NULL OR pics.e_fireDate > getDate())
ORDER BY pics.c_name;
我想你需要输出最近的计划假期的员工(?然后,您应该使用左加入加入已经准备好的表et_vacations
以防某些员工的假期记录为空:
WITH T_vac as
(
select et_vacations.*,
ROW_NUMBER() OVER (PARTITION BY e_pic ORDER BY e_dateTo) as RowNum
from et_vacations
where e_dateTo>=getDate()
)
SELECT
pics.c_name,
pics.e_post,
vac. e_dateFrom,
vac.e_dateTo
FROM et_pics pics
LEFT JOIN T_vac vac on (vac.e_pic = pics.ob_no) AND (vac.RowNum=1)
ORDER BY pics.c_name;
SQLFiddle demo
我自己用CTE解决了这个问题,但HLGEM是第一个:
;WITH Vacations_nah AS
(
SELECT
vac.e_pic,
MAX(vac.e_dateTo) AS e_dateTo_2
FROM et_vacations vac
WHERE e_dateTo >=getDate()
GROUP BY vac.e_pic
)
SELECT
pics.c_name,
pics.e_post,
e_dateTo_2
FROM et_pics pics
INNER JOIN et_division div on pics.e_division = div.ob_no
LEFT JOIN Vacations_nah nah on nah.e_pic = pics.ob_no
WHERE
(pics.e_fireDate IS NULL OR pics.e_fireDate > getDate())
AND pics.c_visible=1