1

一部のビジネス アプリケーションでは、生データが入ってきて、それらを正規化して処理し、レポート目的で保存します。

たとえば、生データ:

Transaction (transaction ID, employee 1 ID, employee 2 ID, employee 3 ID)

に正規化されます

Transaction(transaction ID)

TransactionEmployee (transaction ID, employee ID)

報告要件に関しては、従業員は 1 行に表示する必要があります。TransactionReport(transaction ID, some details, employee 1 ID, employee 2 ID, employee 3 ID)

私の解決策は、アプリケーション プログラミング言語を使用して TransactionEmployee をループし、INSERT ステートメントを作成してレポート データを別のテーブルに配置することでした。各トランザクションには 3 つの従業員 ID があります。

しかし、SQLでそれを行う方が快適だと思います。

これはSQL経由で実行可能ですか?

4

1 に答える 1

0

これを行う 1 つの方法は、ユーザー定義変数を使用して、トランザクションごとに各従業員の行番号を作成することです。次に、CASE 式を使用して集計関数を適用することにより、データの行を列に変換できます。

select transactionid,
  max(case when row = 1 then employeeid end) employee1,
  max(case when row = 2 then employeeid end) employee2,
  max(case when row = 3 then employeeid end) employee3
from
(
  select t.transactionid,
    e.employeeid,
    @row:=case when @prev = t.transactionid then @row else 0 end +1 row,
    @prev:=t.transactionid
  from transaction t
  left join transactionemployee e
    on t.transactionid = e.transactionid
  cross join (select @row:=0, @prev = 0) c
  order by t.transactionid, e.employeeid
) d
group by transactionid
order by transactionid;

SQL Fiddle with Demoを参照してください。

ユーザー定義変数を使用したくない場合は、次のようなサブクエリを使用できます。

select transactionid,
  max(case when row = 1 then employeeid end) employee1,
  max(case when row = 2 then employeeid end) employee2,
  max(case when row = 3 then employeeid end) employee3
from
(
  select t.transactionid,
    e.employeeid,
    (select count(*)
     from transactionemployee te
     where e.transactionid = te.transactionid
       and te.employeeid <= e.employeeid) row
  from transaction t
  left join transactionemployee e
    on t.transactionid = e.transactionid
) d
group by transactionid;

デモで SQL Fiddle を参照してください

于 2013-08-07T01:04:31.073 に答える