0

伙计们,我所寻找的只是扩展 INNER JOIN。让我进入正题。我有两张桌子 Dept & Emp。一个部门可以有多个 Emp's 而不是相反。

餐桌部
Dept_id Dept_Name
1 IT
2 小时
3 其他

表 Emp
Emp_id Dept_id Emp_Name
11 1约翰
12 1 吉尔
13 2 杰克
14 3 贾里德
15 1 吉姆
16 1 贾雷特
17 2 雅各布

我需要在 Dept_id 上加入它

预期成绩
Dept_id Dept_name Emp_id Emp_Name
1 IT 11 约翰
NULL NULL 12 吉尔
NULL NULL 15 吉姆
NULL NULL 16 贾雷特
2 小时 13 杰克
NULL NULL 17 雅各布
3 其他 14 杰瑞德

希望我准确地传达了我想要的东西。它只是外键约束上的常规内部连接。但是,我希望第一个表(部门)中的值除第一个匹配项之外为 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 贾雷特

或者

另外两种可能。

提前致谢。很抱歉,尽管它是一个简单的案例,但解释很长。

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

老实说,我不确定你为什么想要这个结果。格式化通常最好留给 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 回答
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 回答
0

正如我在上面的评论中提到的,我不确定您是否真的希望结果以您要求的方式返回。考虑一下。如果结果集被导出到 Excel,并且用户更改了排序,那么您将丢失员工 1-x 所在的部门,而员工 0 仍会显示他们的部门。我建议您按 Dept_id 分组,而不是将 dept_id 和 dept_name 归零。在显示代码中处理该数据的显示。

于 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 回答
0

因为我想不出你想要其他报告目的的原因,所以你也可以通过使用 SQL*Plus 格式化来做到这一点。

只需在 SQL*Plus 中的查询之前运行以下命令

break on dept_id skip 1

享受。

于 2013-02-10T15:11:05.050 回答