在子查询条件下连接两个表的问题

时间:2016-02-10 14:14:04

标签: sql sql-server sql-server-2005

我有两张桌子:

1)et_pics - 这里有关员工的信息:

  • ob_no,int,key,例如2020
  • c_name,varchar,例如Dribbler D.E。
  • e_post,varchar,例如主席

    SELECT * FROM et_pics:

  

ob_no | c_name | e_post

     

2020 | Dribbler D.E. |主席

2)et_vacations - 此处存储有关休假的信息:

  • ob_no,int,例如666 e_pic,int,与pic.ob_no的连接,例如2020
  • c_name,varchar,例如假期等等。
  • e_dateFrom,date,例如2010-08-08 00:00:00.000
  • e_dateTo,date,eg 2010-08-09 00:00:00.000

    SELECT * FROM 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:

  • 每个人可能只有一张假期记录(在我看来 MAX(e_dateTo));
  • 休假记录必须是> = getDate()或null 显示。

无法理解如何编写正确的子查询 - 以这种方式尝试,但没有运气:

// adds the nonzero elements of the array to the new array
int l = count;

for (int j=0; j < n; ++j)
{
    if (a[j] != 0)
    {
        array = realloc(array, (l+1) * sizeof(int));
        array[l] = a[j];
        ++l;
    }
}

3 个答案:

答案 0 :(得分:1)

我相信您的问题需要更多关于您感兴趣的假期日期(开始日期?,结束日期?)的定义,但这是一个开始。注意我已将连接保留为除法,因为您已经使用了它,但是您没有在任何select字段或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;

答案 1 :(得分:1)

我猜你需要输出最近计划休假的员工(?)。那么你应该使用LEFT JOIN加入已准备好的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

答案 2 :(得分:0)

我独自一人参加了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