需要Sql Query来生成如下表所示的输出

时间:2015-07-30 09:23:31

标签: mysql sql-server

在此示例中,三个表用于Employee,EmployeeWork和EmployeeEducation。

Employee表有两个数据行。

员工有六个数据行,第三个用于第一个员工,另外三个用于第二个员工。

最后,EmployeeEducation有四个数据行,第一个员工两个,下一个员工两个。

我想要输出(如果可能或替代解决方案),如上表输出样本中所示。

Employee
+--------------------------+
|empId | empName | empPhone|
+--------------------------+
|1     | John    | 1234    |
|2     | Rick    | 5678    |
+--------------------------+

EmployeeWork
+--------------------------------------------+
|empWrkId | empId | DepartmentName | WorkYrs |
+--------------------------------------------+
|1        | 1     | Support        | 2       |
|2        | 1     | Development    | 3       |
|3        | 1     | Retail         | 5       |
+--------------------------------------------+
|4        | 2     | Support        | 1       |
|5        | 2     | Development    | 3       |
|6        | 2     | Retail         | 6       | 
+--------------------------------------------+

EmployeeEducation
+-----------------------------------------+
|empEduId | empId | EduName | Division    |
+-----------------------------------------+
|1        | 1     | Inter   | First       |
|2        | 1     | Bachelor| Second      |
+-----------------------------------------+
|3        | 2     | Bachelor| First       |
|4        | 2     | Masters | Distinction |
+-----------------------------------------+

What can we do to get the output as below combining above three tables?

Output Sample
+--------------------------------------------------------------------+
| empId | empName | DepartmentName | WorkYrs | EduName | Division    |
+--------------------------------------------------------------------+
| 1     | John    | Support        | 2       | Inter   | First       |
| 1     | John    | Development    | 3       | Bachelor| Second      |
| 1     | John    | Retail         | 5       | NULL    | NULL        |
+--------------------------------------------------------------------+
| 2     | Rick    | Support        | 1       | Bachelor| First       |
| 2     | Rick    | Development    | 3       | Masters | Distinction |
| 2     | Rick    | Retail         | 6       | NULL    | NULL        |
+--------------------------------------------------------------------+

5 个答案:

答案 0 :(得分:1)

由于教育与工作之间没有实际关系,您需要创建一个,从您的示例输出中看起来好像您只是按ID排序,因此对于每个表,您可以应用ROW_NUMBER()来获取要加入的字段:

/******************************************************************************************
GENERATE TABLES AND SAMPLE DATA
******************************************************************************************/
DECLARE @Employee TABLE (empId INT, empName VARCHAR(50), empPhone INT);
INSERT @Employee VALUES (1, 'John', 1234), (2, 'Rick', 5678);

DECLARE @EmployeeWork TABLE (empWrkId INT, empId INT, DepartmentName VARCHAR(50), WorkYrs INT);
INSERT @EmployeeWork
VALUES 
    (1, 1, 'Support', 2), (2, 1, 'Development', 3), (3, 1, 'Retail', 5), 
    (4, 2, 'Support', 1), (5, 2, 'Development', 3), (6, 2, 'Retail', 6)


DECLARE @EmployeeEducation TABLE (empEduId INT, empId INT, EduName VARCHAR(50), Division VARCHAR(50));
INSERT @EmployeeEducation
VALUES
    (1, 1, 'Inter', 'First'), (2, 1, 'Bachelor', 'Second'),
    (3, 2, 'Bachelor', 'First'), (4, 2, 'Masters', 'Distinction');


/******************************************************************************************
ACTUAL QUERY
******************************************************************************************/
WITH EmpEd AS
(   SELECT  EmpID,
            EduName,
            Division,
            RowNumber = ROW_NUMBER() OVER(PARTITION BY empID ORDER BY empEduID)
    FROM    @EmployeeEducation
), EmpWork AS
(   SELECT  EmpID,
            DepartmentName,
            WorkYrs,
            RowNumber = ROW_NUMBER() OVER(PARTITION BY empID ORDER BY empWrkId)
    FROM    @EmployeeWork
)
SELECT  e.EmpID,
        e.EmpName,
        ee.DepartmentName,
        ee.WorkYrs,
        ee.EduName,
        ee.Division,
        ee.RowNumber,
        EmpName2 = CASE WHEN ee.RowNumber = 1 THEN e.EmpName ELSE '-' END
FROM    @Employee AS e
        LEFT JOIN
        (   SELECT  EmpID = ISNULL(w.EmpID, e.EmpID),
                    RowNumber = ISNULL(w.RowNumber, e.RowNumber),
                    w.DepartmentName,
                    w.WorkYrs,
                    e.EduName,
                    e.Division
            FROM    EmpWork AS w
                    FULL JOIN EmpEd AS e
                        ON e.EmpID = w.EmpID
                        AND e.RowNumber = w.RowNumber
        ) AS ee
            ON ee.EmpID = e.EmpID
ORDER BY e.EmpID;

我已将EduName保留为NULL,但没有匹配,更改-的空值可能是留给表示层的最佳工作,同样我已离开{{1并且每行重复一次,因为选择是否显示它应该再次成为表示层的作业,但是我在末尾添加了一列empID,它显示了你如何能够使用EmpName列确定是否显示列名。

答案 1 :(得分:0)

我认为这些SQL对你有用。

select ew.empId , e.empName , ew.DepartmentName , ew.WorkYrs , ee.EduName , ee.Division     
from Employee e, EmployeeWork ew, EmployeeEducation ee where
e.empId= ew.empId and e.empId= ee.empId

谢谢。

答案 2 :(得分:0)

你也可以这样:

select a.empId,a.empName,a.DepartmentName,a.WorkYrs,b.EduName,b.Division from (
select e.empId,e.empName,
w.DepartmentName,w.WorkYrs,w.empWrkId
from employee e 
left join EmployeeWork w on e.empId = w.empId) a 
left join (
select em.EduName,em.Division,en.empWrkId from EmployeeEducation  em left join EmployeeWork en on em.empId = en.empID
group by en.empId) b on a.empWrkId = b.empWrkId

答案 3 :(得分:0)

SELECT ew.empId, e.empName, ew.DepartmentName, 
       ew.WorkYrs, ee.EduName, ee.Division
FROM Employee
LEFT JOIN EmployeeWork ON e.empId= ew.empId
LEFT JOIN EmployeeEducation ON e.empId= ee.empId
GROUP BY e.empId 

答案 4 :(得分:0)

您可以将join与left join结合使用以获得此结果 检查此查询 - 检查列名称后 -

   select e.empId as id , e.empName ,  ew.DepartmentName , ew.WorkYrs  , edu.EduName , edu.Division
 from employee e
join EmployeeWork ew on ew.empId  = id
left join EmployeeEducation edu on edu.empEduId = empEduId