多个表选择,Subquery返回多个值。 SQL

时间:2016-12-02 10:58:51

标签: mysql sql select multiple-tables

我有两张桌子:

员工

id  | fullName   | birth      | speciality
1   | A A A      | 01/01/1980 | Manager
2   | B B B      | 01/01/1980 | Developer
3   | C C C      | 01/01/1980 | User

EmployeesStatus

ID  | status     | dateChange
1           | 1          | 01/01/2010
2           | 1          | 01/01/2013
3           | 1          | 01/01/2015
3           | 2          | 01/01/2016

我希望选择以下数据

ID | Full name | Bith date | speciality | Date hired | Date fired

结果必须是:

ID | Full name    | Bith date   | speciality | Date hired | Date fired
1  | A A A        | 01/01/1980  | Manager    | 01/01/2010 | null
2  | B B B        | 01/01/1980  | Developer  | 01/01/2013 | null
3  | C C C        | 01/01/1980  | User       | 01/01/2015 | 01/01/2016
3  | C C C        |01/01/1980   | User       | 01/01/2017 | null

我的代码:

 SELECT Employees.id , Employees.fullName, Employees.birth, Employees.speciality,
(SELECT dateChange FROM EmployeesStatus WHERE status=1 AND id=Employees.id) datehired,
(SELECT dateChange FROM EmployeesStatus WHERE status=2 AND id=Employees.id) datefired FROM Employees

结果以下消息:

  

Msg 512,Level 16,State 1,Line 1 Subquery返回的值超过1   值。当子查询遵循=,!=,<,< =,

时,不允许这样做      
    

,> =或当子查询用作表达式时。

  

有什么想法吗?

4 个答案:

答案 0 :(得分:1)

您应该使用连接而不是基于子查询的<= p>

SELECT 
    Employees.id 
  , Employees.fullName
  , Employees.birth
  , Employees.speciality
  , e1.dateChange as datehired, e2.dateChange as datefired
FROM Employees
INNER JOIN EmployeesStatus es1 on e1.status=1 AND e1.id=Employees.id
LEFT JOIN EmployeesStatus es2 on e2.status=2 AND e2.id=Employees.id

或者你可以在子句中使用in子句代替=

答案 1 :(得分:0)

请尝试以下操作:

SELECT E.ID,E.FULLNAME,E.BIRTH,E.SPECIALITY,ED.DATE_HIRED,ED.DATE_FIRED
FROM EMPLOYEES E,
(SELECT     ID,
        MAX(CASE WHEN STATUS=1 THEN DATECHANGE ELSE NULL END)DATE_HIRED,
        MAX(CASE WHEN STATUS=2 THEN DATECHANGE ELSE NULL END)DATE_FIRED
FROM EMPLOYEESSTATUS
GROUP BY ID)ED
WHERE E.ID=ED.ID

此查询在性能方面会更快,并会给您相同的结果。

答案 2 :(得分:0)

除了@scaisEdge回答:

SELECT 
    Employees.id,
    Employees.fullName,
    Employees.birth,
    Employees.speciality
    e1.dateChange as datehired, 
    MIN(e2.dateChange) as datefired
FROM Employees
INNER JOIN EmployeesStatus es1 on e1.status=1 AND e1.id=Employees.id
LEFT JOIN EmployeesStatus es2 on e2.status=2 AND e2.id=Employees.id
    AND e2.dateChange > e1.dateChange
GROUP BY Employees.id, 
    Employees.fullName,
    Employees.birth,
    Employees.speciality,
    e1.dateChange

答案 3 :(得分:0)

试试这个

 SELECT e.id , 
        e.fullName,
        e.birth,
        e.speciality,   
        CASE WHEN t1.status = 1 then max(t1.dateChange) else null end as "Date Hired",
        CASE WHEN t2.status = 2 then max(t2.dateChange) else null end as "Date Fired",
    FROM Employees e
    LEFT JOIN EmployeesStatus t1 on t1.id = e.id and t1.status = 1
    LEFT JOIN EmployeesStatus t2 on t2.id = e.id and t1.status = 2

希望这有效..