0

みなさん、探しているのはINNER JOINを拡張することです。要点を説明しましょう。DeptとEmpの2つのテーブルがあります。1 つの部門に複数の Emp を配置できますが、その逆はできません。

テーブル部門
Dept_id Dept_Name
1 IT
2時間
3 その他

表従業員
Emp_id Dept_id Emp_Name
11 1 ジョン
12 1 ジル
13 2 ジャック
14 3 ジャレド
15 1 ジム
16 1 ジャレット
17 2 ジェイコブ

Dept_id で JOIN する必要があります

予想された結果
Dept_id Dept_name Emp_id Emp_Name
1 IT 11 ジョン
NULL NULL 12 ジル
NULL NULL 15 ジム
NULL NULL 16 ジャレット
2 HR 13 ジャック
NULL NULL 17 ジェイコブ
3 その他 14 ジャレド

私が欲しいものを正確に伝えてくれることを願っています。外部キー制約に対する通常の内部結合です。しかし、最初の一致を除いて、最初のテーブル (Dept) の値を NULL にする必要があります。そうは言っても、最初の試合が何であるかは気にしません。以下を参照してください - Dept_id 1 の結果のみ。

期待される結果 (Dept_id = 1 の場合のみ)
かもしれない

Dept_id Dept_name Emp_id Emp_Name
1 IT 11 ジョン
NULL NULL 12 ジル
NULL NULL 15 ジム
NULL NULL 16 ジャレット

また

Dept_id Dept_name Emp_id Emp_Name
1 IT 15 ジム
NULL NULL 12 ジル
NULL NULL 11 ジョン
NULL NULL 16 ジャレット

また

他に 2 つの可能性があります。

前もって感謝します。単純なケースなのに説明が長くなってすみません。

4

6 に答える 6

5

私はIcに同意します。これは、SQLクエリの代わりにアプリケーションが行うべきことをしているように見えるクレイジーなクエリです。そうは言っても、これらのクエリを書くのは楽しいです:)

SELECT CASE WHEN RowNumber = 1 THEN Dept_id ELSE NULL END AS Dept_id,
       CASE WHEN RowNumber = 1 THEN Dept_name ELSE NULL END AS Dept_name,
        Emp_id, Emp_Name
FROM Dept d
INNER JOIN 
(SELECT ROW_NUMBER() OVER (PARTITION BY Dept_id ORDER BY Emp_Name) AS RowNumber, 
       Dept_id, Dept_name, Emp_id, Emp_Name
FROM Emp ) t on t.Dept_id = d. Dept_id
于 2013-02-08T17:32:15.950 に答える
1
select case
          when lag(d.dept_id) over (partition by d.dept_id order by e.emp_id) = d.dept_id then null
          else d.dept_id 
       end as dept_id,
       case
          when lag(d.dept_name) over (partition by d.dept_id order by e.emp_id) = d.dept_name then null
          else d.dept_name 
       end as dept_name,
       e.emp_id,
       e.emp_name
from dept d
  join emp e on e.dept_id = d.dept_id
order by d.dept_id, d.dept_name, e.emp_id
于 2013-02-08T17:33:05.763 に答える
1

正直なところ、なぜこの結果が必要なのかよくわかりません。書式設定は、通常、データベース サーバーではなく、UI レイヤーに残すのが最適です。このようにすると、各部門の最初の従業員ではない従業員が実際には部門を持たないようにデータが表示され、クライアントにあるソートまたは編集機能が根本的に壊れます。

ただし、次のことを試すことができます。

SELECT FormattedDept.Dept_id, FormattedDept.Dept_Name, Emp.Emp_id, Emp.Emp_Name
FROM Emp
LEFT OUTER JOIN
(
    SELECT Dept.Dept_id, Dept.Dept_Name, MIN(Emp_id) AS Emp_id
    FROM Dept
    INNER JOIN Emp ON Dept.Dept_id = Emp.Dept_id
    GROUP BY Dept.Dept_id, Dept.Dept_Name
) FormattedDept ON Emp.Dept_id = FormattedDept.Dept_id
    AND Emp.Emp_id = FormattedDept.Emp_id
ORDER BY Emp.Dept_id, Emp.Emp_id

SQL フィドルのデモ

于 2013-02-08T17:30:52.483 に答える
0

レポート以外の目的で必要な理由が思いつかないので、SQL*Plus フォーマットを使用してこれを行うこともできます。

SQL*Plus でクエリの前に次のコマンドを実行するだけです。

break on dept_id skip 1

楽しみ。

于 2013-02-10T15:11:05.050 に答える
0

上記のコメントで述べたように、あなたが求めている方法で結果が返されることを本当に望んでいるかどうかはわかりません。このことを考慮。結果セットが Excel にエクスポートされ、ユーザーが並べ替えを変更した場合、従業員 1-x が所属していた部門が失われ、従業員 0 には引き続き部門が表示されます。Dept_id でグループ化し、dept_id と dept_name を null にしないことをお勧めします。表示コードでそのデータの表示を処理します。

于 2013-02-08T17:33:24.830 に答える
0
WITH newRecord
AS
(
   SELECT "Emp_id", "Dept_id", "Emp_Name",
           ROW_NUMBER() OVER (PARTITION BY "Dept_id" ORDER BY "Emp_id" ASC) RN
   FROM Emp  
)
SELECT  CASE WHEN RN = 1 THEN b."Dept_id" ELSE NULL END AS "Dept_ID",
        CASE WHEN RN = 1 THEN b."Dept_Name" ELSE NULL END AS "Dept_Name",
        "Emp_id", "Emp_Name"
FROM    newRecord a 
        INNER JOIN Dept b ON a."Dept_id" = b."Dept_id"
于 2013-02-08T17:35:13.453 に答える