这个sql内连接有什么问题?
这是我的 select 语句,其中包含两个表的内连接,
if not exists(select EmpId from SalaryDetails
where EmpId in (select Emp_Id
from Employee where Desig_Id=@CategoryId))
begin
// some statements here
end
else
begin
SELECT e.Emp_Id, e.Identity_No, e.Emp_Name,
case WHEN e.SalaryBasis=1 THEN 'Weekly'
ELSE 'Monthly' end as SalaryBasis,e.FixedSalary,
(SELECT TOP 1 RemainingAdvance
FROM SalaryDetails
ORDER BY CreatedDate DESC) as Advance
FROM Employee as e inner join Designation as d on e.Desig_Id=d.Desig_Id
INNER JOIN SalaryDetails as S on e.Emp_Id=S.EmpId
End
我的结果窗格,
alt text http: //img220.imageshack.us/img220/7774/resultpane.jpg
和我的薪资详细信息表,
替代文本http://img28.imageshack.us/img28/770/salarydettable.jpg
编辑: 我的输出必须是,
16 CR14 Natarajan 每周 150.00 354.00
17 cr12333 盘点周刊 122.00 0.00
Here is my select statement with the innerjoin of two tables,
if not exists(select EmpId from SalaryDetails
where EmpId in (select Emp_Id
from Employee where Desig_Id=@CategoryId))
begin
// some statements here
end
else
begin
SELECT e.Emp_Id, e.Identity_No, e.Emp_Name,
case WHEN e.SalaryBasis=1 THEN 'Weekly'
ELSE 'Monthly' end as SalaryBasis,e.FixedSalary,
(SELECT TOP 1 RemainingAdvance
FROM SalaryDetails
ORDER BY CreatedDate DESC) as Advance
FROM Employee as e inner join Designation as d on e.Desig_Id=d.Desig_Id
INNER JOIN SalaryDetails as S on e.Emp_Id=S.EmpId
End
My results pane,
alt text http://img220.imageshack.us/img220/7774/resultpane.jpg
And My SalaryDetails Table,
alt text http://img28.imageshack.us/img28/770/salarydettable.jpg
EDIT:
My Output must be,
16 CR14 Natarajan Weekly 150.00
354.00
17 cr12333 Pandian Weekly 122.00 0.00
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您没有过滤任何员工 ID 上的子查询 (
SELECT TOP 1 RemainingAdvance FROM SalaryDetails ORDER BY CreatedDate DESC
),因此当按排序时,它会为您提供整个表中的第一条记录CreatedDate DESC
(我猜是 354。)您可能希望将该表表达式移动到 FROM 子句中,而不是您的 SELECT 中,包括您的员工 ID,并对该表达式进行联接。
这只是我的想法,所以可能需要一些调整才能正确运行。另请注意 RANK() 函数的使用 - 如果您使用 TOP 1,您只能获得整个表的第一条记录。您需要的是每个员工 ID 的第一条记录。
如果是我,我可能会将该表表达式设为视图,甚至是标量值函数,获取您的员工 ID 并返回第一个 RemainingAdvance 值,然后您可以使用 TOP 1 并过滤员工 ID。
You're not filtering the sub-query (
SELECT TOP 1 RemainingAdvance FROM SalaryDetails ORDER BY CreatedDate DESC
) on any employee ID, so it's giving you the first record in the entire table when sorted byCreatedDate DESC
(which I'm guessing is 354.)You will probably want to move that table expression into your FROM clause, not your SELECT, include your employee ID, and do a join on that expression.
This is just off the top of my head so may take a bit of tweaking to run correctly. Note also the use of the RANK() function - if you use TOP 1, you're only ever getting the first record of the entire table. What you need is the first record per employee ID.
If this was me I would probably make that table expression a view or even a scalar-valued function taking your employee ID and returning the first RemainingAdvance value, then you could use TOP 1 and filter on the employee ID.
看起来您甚至没有使用对 Designation 的连接,并且您还缺少在顶部 IF 语句中使用的 WHERE 子句。我还将子查询向下移动到连接中,就像安迪指出的那样。如果没有数据库来测试这一点可能不准确,但我会将其重写为类似的内容;
Andy 建议将子查询移至视图中,这是一个很好的建议,更容易阅读,而且如果数据库很大的话,效率可能会更高。
编辑:(答案)
我编辑了杰伊的答案,因为他接近我的输出......
It looks like your join to Designation isn't even used and you're also missing your WHERE clause that you used in the IF statement at the top. I'd also move the subquery down into the join like Andy pointed out. Without having the DB to test against this probably won't be exact but I'd rewrite it to something like;
Andy's suggestion to move the subquery into a view is a good one, much easier to read and probably a lot more efficient if the DB is large.
EDIT: (ANSWER)
I edited jay's answer because he came close to my output...