此sql select语句中有什么错误?
这是我的选择声明此sql select语句中有什么错误?,sql,sql-server,sql-server-2005,tsql,Sql,Sql Server,Sql Server 2005,Tsql,这是我的选择声明 SELECT TOP 1 EmpId, RemainingAdvance FROM SalaryDetails WHERE EmpId IN (SELECT Emp_Id FROM Employee WHERE Desig_Id='27') ORDER BY CreatedDate DESC 当我执行selectemp\u Id FROM Employee WHERE Desig\u Id='27'时,结果
SELECT TOP 1
EmpId, RemainingAdvance
FROM SalaryDetails
WHERE EmpId IN (SELECT Emp_Id
FROM Employee
WHERE Desig_Id='27')
ORDER BY CreatedDate DESC
当我执行selectemp\u Id FROM Employee WHERE Desig\u Id='27'
时,结果是
Emp_Id16
17 但当我执行第一条语句时,它只给出
16
的结果,而没有输出17
。。。
我在工资明细表中有两个EmpId的记录
编辑:
从我的查询中删除前1我得到了这个
SELECT EmpId, RemainingAdvance FROM SalaryDetails
where EmpId in (select Emp_Id from Employee where Desig_Id='27')
ORDER BY CreatedDate DESC
给我
我想要CreatedDate DESC的EmpId 16,17的结果。。。因为现在我的设计Id='27'
,我将使用变量@CategoryId
对其进行更改。。。因此,根据@CategoryId
EmpId RemainingAdvance
16 354.00
17 0.00
SELECT TOP 1
只返回一行
您可以尝试使用选择前10名
编辑:
您总是会得到16
,因为它似乎具有较高的CreatedDate
,您可以按该列降序进行排序。选择顶部1
只返回一行
您可以尝试使用选择前10名
编辑:
您总是会得到16
,因为它似乎具有较高的CreatedDate
,您可以按该列降序排序。选择顶部1将选择一个顶部行。如果您想查看所有列表,请丢失前1行。选择“前1行”将选择一行。如果要使用CTE和行号查看所有SQL Server 2005+,请删除前1名:
SQL Server 2005+,非CTE等效项
参考:
SQL Server 2005+,使用CTE和行号:
SQL Server 2005+,非CTE等效项
参考:
注意:该查询是在未尝试的情况下编写的。
我想,这就是你要找的
此变体也可以工作(至少在一个DBMS中,即IBM Informix Dynamic Server 11.50):
first ON子句中的复合联接可能会提高查询的性能,但优化器很可能会提升'AND SD.CreatedDate=SD2.MaxDate'条件,这意味着您即使检查了两个查询计划,也不会发现任何差异。我不太确定在main FROM子句之后缩进表表达式的最佳方法
由Jonathan Leffler编辑-根据Shahkalpesh的要求
注意:该查询是在未尝试的情况下编写的。
我想,这就是你要找的
此变体也可以工作(至少在一个DBMS中,即IBM Informix Dynamic Server 11.50):
first ON子句中的复合联接可能会提高查询的性能,但优化器很可能会提升'AND SD.CreatedDate=SD2.MaxDate'条件,这意味着您即使检查了两个查询计划,也不会发现任何差异。我不太确定在main FROM子句之后缩进表表达式的最佳方法
Jonathan Leffler编辑-应Shahkalpesh的要求。该声明按照您的要求执行,但不是按照您的预期执行
我猜您希望为每个具有特定设计ID的员工提供最新的工资明细记录:
SELECT EmpId, RemainingAdvance
FROM SalaryDetails
WHERE CreatedDate IN
(SELECT MAX(d.CreatedDate)
FROM SalaryDetails d
INNER JOIN Employee e ON d.EmpId = e.EmpId
WHERE e.Desig_Id = '27'
AND SalaryDetails.EmpId = d.EmpId
)
该语句按照它告诉您的方式执行,但不是按照您的意图执行
我猜您希望为每个具有特定设计ID的员工提供最新的工资明细记录:
SELECT EmpId, RemainingAdvance
FROM SalaryDetails
WHERE CreatedDate IN
(SELECT MAX(d.CreatedDate)
FROM SalaryDetails d
INNER JOIN Employee e ON d.EmpId = e.EmpId
WHERE e.Desig_Id = '27'
AND SalaryDetails.EmpId = d.EmpId
)
这是可行的,但相关子查询效率不高:
CREATE TABLE employee
(
empid INTEGER NOT NULL PRIMARY KEY,
desig_id CHAR(2) NOT NULL
);
INSERT INTO employee VALUES(16, '27');
INSERT INTO employee VALUES(17, '27');
INSERT INTO employee VALUES(15, '13');
INSERT INTO employee VALUES(18, '9');
CREATE TABLE salarydetails
(
empid INTEGER NOT NULL REFERENCES employee,
createdate DATE NOT NULL,
PRIMARY KEY (empid, createdate),
remainingAdvance DECIMAL(10,2) NOT NULL
);
INSERT INTO salarydetails VALUES (15, '2009-12-13', 1534.00);
INSERT INTO salarydetails VALUES (16, '2010-01-31', 3634.00);
INSERT INTO salarydetails VALUES (16, '2010-02-14', 2634.00);
INSERT INTO salarydetails VALUES (17, '2010-01-03', 5734.00);
INSERT INTO salarydetails VALUES (17, '2010-02-03', 4734.00);
INSERT INTO salarydetails VALUES (17, '2010-03-01', 3734.00);
INSERT INTO salarydetails VALUES (18, '2010-01-13', 5834.00);
SELECT s1.empid, s1.remainingAdvance
FROM SalaryDetails AS s1
WHERE s1.empid IN (SELECT e.empid FROM employee AS e WHERE e.desig_id = '27')
AND s1.createdate = (SELECT MAX(s2.createdate)
FROM salarydetails AS s2
WHERE s2.empid = s1.empid);
结果:
EmpID RemainingAdvance
16 2634.00
17 3734.00
这是可行的,但相关子查询效率不高:
CREATE TABLE employee
(
empid INTEGER NOT NULL PRIMARY KEY,
desig_id CHAR(2) NOT NULL
);
INSERT INTO employee VALUES(16, '27');
INSERT INTO employee VALUES(17, '27');
INSERT INTO employee VALUES(15, '13');
INSERT INTO employee VALUES(18, '9');
CREATE TABLE salarydetails
(
empid INTEGER NOT NULL REFERENCES employee,
createdate DATE NOT NULL,
PRIMARY KEY (empid, createdate),
remainingAdvance DECIMAL(10,2) NOT NULL
);
INSERT INTO salarydetails VALUES (15, '2009-12-13', 1534.00);
INSERT INTO salarydetails VALUES (16, '2010-01-31', 3634.00);
INSERT INTO salarydetails VALUES (16, '2010-02-14', 2634.00);
INSERT INTO salarydetails VALUES (17, '2010-01-03', 5734.00);
INSERT INTO salarydetails VALUES (17, '2010-02-03', 4734.00);
INSERT INTO salarydetails VALUES (17, '2010-03-01', 3734.00);
INSERT INTO salarydetails VALUES (18, '2010-01-13', 5834.00);
SELECT s1.empid, s1.remainingAdvance
FROM SalaryDetails AS s1
WHERE s1.empid IN (SELECT e.empid FROM employee AS e WHERE e.desig_id = '27')
AND s1.createdate = (SELECT MAX(s2.createdate)
FROM salarydetails AS s2
WHERE s2.empid = s1.empid);
结果:
EmpID RemainingAdvance
16 2634.00
17 3734.00
@彼得,我只能用第一名。。。我可以得到empid=16
的记录,但不能得到empid=17
@Pandiya的记录:如果你说“TOP 1”,你只能得到一行(empid=16的那一行)。如果你的意思是“每个不同的emp_id都有一个顶级的”,那么你需要一个完全不同(而且更复杂)的查询。@Pandiya Chendur:我已经编辑了我的答案。如果我遗漏了什么,请提供更多信息:)如果你有正当理由想要在这种情况下获得TOP 1,你可能需要做一些规范化工作。@Peter我只能使用TOP 1。。。我可以得到empid=16
的记录,但不能得到empid=17
@Pandiya的记录:如果你说“TOP 1”,你只能得到一行(empid=16的那一行)。如果你的意思是“每个不同的emp_id都有一个顶级的”,那么你需要一个完全不同(而且更复杂)的查询。@Pandiya Chendur:我已经编辑了我的答案。如果我遗漏了什么,请提供更多信息:)如果你有正当理由想要在这种情况下排名第一,你可能需要做一些规范化工作。@Peter我将为你编辑它…请尝试@OMG Ponies所说的(使用CTE,RANK)。看看它是否在性能和可读性方面对您有所帮助。您是否已经确定了您的查询失败的原因,以及我认为它应该起作用的方式。假设在SalaryDetails表中有一行是EmpId的16和17。@Peter我会为您编辑它…请尝试@OMG Ponies所说的(使用CTE,RANK)。看看它是否在性能和可读性方面对您有所帮助。您是否已经确定了您的查询失败的原因,以及我认为它应该起作用的方式。假设SalaryDetails表中有一行是EmpId的16和17。请尝试并查看@OMG Ponies的示例是否也适用。我认为他的解决方案是优雅的,而且在性能方面可能会更好。还有,为什么不使用可用的语言功能呢?你会学到一些新的做事方法:)+1:我喜欢这个答案,因为它不依赖于解析函数。它可以在MySQL和Oracle上运行。如果将'AND SD.CreatedDate=SD2.MaxDate'子句上移到'on SD.EmpID=SD2.EmpID'子句,性能会有所提高吗。优化器会这样做吗?(鉴于我的答案中的样本数据,您的书面查询和我建议的变体都产生了与m相同的答案
EmpID RemainingAdvance
16 2634.00
17 3734.00