在子查询条件下连接两个表时出现问题



我有 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

最新更新