SQL Select Query(员工和工作职位)

时间:2012-06-20 15:47:34

标签: sql sybase

我有2张桌子

1)表位

pos_id, pos_description, pos_total(maximum # of employees for that position)

    1     c++ Developer     3
    2     Java Developer    2
    3     DBA               3

2)表员工

emp_id, emp_pos_id 
1       1
2       1
3       2
4       3
5       3
6       3

我想在SQL Server或Sybase中创建以下报告:

 Position Pos. Description     Serial No of Position  ID of Employee
    1     C++ Developer        1                      1
    1     C++ Developer        2                      2
    1     C++ Developer        3                      ------------------
    2     Java Developer       1                      3
    2     Java Developer       2                      ------------------
    3     DBA                  1                      4
    3     DBA                  2                      5
    3     DBA                  3                      6

如何实现此类查询?

3 个答案:

答案 0 :(得分:0)

您想要的基本查询如下:

select p.pos_id, p.pos_description,
       row_number() over (partition by p.pos_id order by e.emp_id) as SerialNumber,
       e.emp_id
from positions p left outer join
     employees e 
     on p.pos_id = e.emp_pos_id
order by 1, 2, 3

问题是这不会返回空位。可以想象,因为每个职位都可能是空的,在这种情况下需要什么?

select p.pos_id, p.pos_description,
       row_number() over (partition by p.pos_id order by p.pos_id) as SerialNumber,
       NULL as emp_id
from position p join
     (select row_number() over (partition by NULL order by pos_id) as seqnum
      from positions
     ) as numbers
     on numbers.seqnum <= p.pos_total

在这里,我只是使用该表来创建数字列表。我将这些加入到可用的位置。

下一个查询使用连接组合了其中两个:

with byemp as (
     select p.pos_id, p.pos_description,
            row_number() over (partition by p.pos_id order by e.emp_id) as SerialNumber,
            e.emp_id
     from positions p left outer join
          employees e 
          on p.pos_id = e.emp_pos_id
   ),
allpos as (
     select p.pos_id, p.pos_description,
            row_number() over (partition by p.pos_id order by p.pos_id) as SerialNumber,
            NULL as emp_id
     from position p join
           (select row_number() over (partition by NULL order by pos_id) as seqnum
            from positions
           ) as numbers
           on numbers.seqnum <= p.pos_total
   )
select allpos.pos_id, allpos.pos_description, allpos.SerialNumber,
       coalesce(byemp.emp_id, allpos.emp_id) as emp_id
from allpos join
     byemp
     on allpos.pos_id = byemp.pos_id and
        allpos.SerialNumber = byemp.SerialNumber

基本上,它保留所有来自allpos的位置信息,但是当它可用时从byemp中引入empid。

答案 1 :(得分:0)

在SQL Server中:

;WITH DummyTable AS (
    SELECT 1 AS Value
    UNION ALL
    SELECT Value + 1 
    FROM DummyTable 
    WHERE Value < 1000 --This value must be least as large as the largest "maximum # of employees for that position"
)
SELECT p.pos_id Position, p.pos_description [Pos. Description], n.Value [Serial No of Position], emp_id [ID of Employee]
FROM DummyTable n
    INNER JOIN Positions p
        ON n.Value <= p.pos_total
    LEFT JOIN (SELECT emp_id, emp_pos_id, ROW_NUMBER() OVER(PARTITION BY emp_pos_id ORDER BY emp_id) AS emp_position FROM Employees) e
        ON e.emp_pos_id = p.pos_id
        AND e.emp_position = n.Value
ORDER BY p.pos_id, n.Value
OPTION (MAXRECURSION 0);

答案 2 :(得分:0)

 with mycte
 as
 (
 select * from pos p inner join dbo.nums n on p.nums >= n.cnt
 ) ,
 em as (select empid,empposid,ROW_NUMBER() over(PARTITION by empposid order by empid) as  rn        from   emp)
 select mc.id as positionid,mc.descr,mc.cnt,isnull(convert(varchar(30),e.empid),'------------') 
 from mycte mc 
 left join em e on mc.id= e.empposid
 and e.rn = mc.cnt

试试这个nums表只是一个表示值为1到1百万的表