这个sql select语句有什么问题?

ACP*_*ACP 1 sql t-sql sql-server sql-server-2005

这是我的选择声明,

SELECT TOP 1
  EmpId, RemainingAdvance 
FROM SalaryDetails
WHERE EmpId IN (SELECT Emp_Id
                FROM Employee
                WHERE Desig_Id='27')
ORDER BY CreatedDate DESC
Run Code Online (Sandbox Code Playgroud)

当我执行SELECT Emp_Id FROM Employee WHERE Desig_Id='27'结果时

Emp_Id
16
17

但是当我执行我的第一个语句时,它只给出了结果16但没有输出17...我在SalaryDetails表格中有两个EmpId的记录.....

编辑:

从我的查询中删除TOP 1我得到了这个,

SELECT EmpId, RemainingAdvance FROM SalaryDetails 
where EmpId in (select Emp_Id from Employee where Desig_Id='27')
               ORDER BY CreatedDate DESC 
Run Code Online (Sandbox Code Playgroud)

给我

alt text http://img189.imageshack.us/img189/6836/resultpane1.jpg

我想要结果EmpId 16,17 ORDER BY CreatedDate DESC...因为我现在我Desig_Id='27'和我将用变量改变它@CategoryId...所以可能有'n'个员工基于@CategoryId

EmpId  RemainingAdvance
16                354.00
17                 0.00
Run Code Online (Sandbox Code Playgroud)

Pet*_*ang 5

SELECT TOP 1 只返回一行.

您可以尝试使用SELECT TOP 10.

编辑:

你总是得到16,因为它似乎有更高的CreatedDate,你按那个列降序排序.


OMG*_*ies 5

SQL Server 2005+,使用CTE和ROW_NUMBER:


WITH summary AS (
    SELECT sd.empid,
           sd.remainingadvance,
           ROW_NUMBER() OVER (PARTITION BY sd.empid ORDER BY sd.createddate DESC) AS rank
      FROM SALARYDETAILS sd
      JOIN EMPLOYEE e ON e.emp_id = sd.empid
                     AND e.desig_id = '27')
SELECT s.empid,
       s.remainingadvance
  FROM summary s
 WHERE s.rank = 1
Run Code Online (Sandbox Code Playgroud)

SQL Server 2005 +,非CTE等效


SELECT s.empid,
       s.remainingadvance
  FROM (SELECT sd.empid,
               sd.remainingadvance,
               ROW_NUMBER() OVER (PARTITION BY sd.empid ORDER BY sd.createddate DESC) AS rank
          FROM SALARYDETAILS sd
          JOIN EMPLOYEE e ON e.emp_id = sd.empid
                         AND e.desig_id = '27') s
 WHERE s.rank = 1
Run Code Online (Sandbox Code Playgroud)

参考:


sha*_*esh 5

SELECT SD.EmpId, SD.RemainingAdvance 
FROM 
SalaryDetails SD INNER JOIN 
   (SELECT SD2.EmpID, MAX(SD2.CreatedDate) AS MAXDate 
   FROM SalaryDetails SD2 GROUP BY SD2.EmpID) AS SD2
ON SD.EmpID = SD2.EmpID
INNER JOIN Employee E
ON SD.EmpID = E.EmpID
WHERE E.Desig_Id = '27' AND SD.CreatedDate = SD2.MaxDate
Run Code Online (Sandbox Code Playgroud)

注意:查询是在不尝试的情况下编写的.
我想,这就是你要找的东西.


此变体也适用(至少在一个DBMS中 - 即IBM Informix Dynamic Server 11.50):

SELECT SD.EmpId, SD.RemainingAdvance 
  FROM SalaryDetails SD
       INNER JOIN 
       (SELECT SD2.EmpID, MAX(SD2.CreatedDate) AS MAXDate 
          FROM SalaryDetails SD2 GROUP BY SD2.EmpID) AS SD2
       ON SD.EmpID = SD2.EmpID AND SD.CreatedDate = SD2.MaxDate
       INNER JOIN Employee E
       ON SD.EmpID = E.EmpID
 WHERE E.Desig_Id = '27'
Run Code Online (Sandbox Code Playgroud)

第一个ON子句中的复合连接可能会提高查询的性能 - 但是优化器很可能会提升'AND SD.CreatedDate = SD2.MaxDate'条件,这意味着即使有任何差异,您也不会发现任何差异.你检查了两个查询计划.我不太确定在主FROM子句之后缩进表表达式的最佳方法.

由Jonathan Leffler编辑 - 按照Shahkalpesh的要求.