我有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
如何实现此类查询?
答案 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百万的表