2

私は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

このようなクエリを実装するにはどうすればよいですか?

4

3 に答える 3

1

必要な基本的なクエリは次のようになります。

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

ここでは、テーブルを使用して数値のリストを作成しています。利用可能な位置までこれらを結合します。

次のクエリは、結合を使用してこれら 2 つを結合します。

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からの位置情報は全てキープしていますが、empidは空きがあればbyempから持ち込んでいます。

于 2012-06-20T16:03:03.947 に答える
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);
于 2012-06-20T16:24:55.387 に答える
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テーブルを試してみてください。100万から100万の値を含む単なるテーブルです。

于 2012-07-13T19:37:53.783 に答える