我试图找到一种不同的方式来使用ROW_NUMBER()
来编写CROSS APPLY
查询,以便可以比较性能。
在下面的简单示例中,创建了一个雇员表,插入了一些测试数据,并使用具有SELECT
窗口函数的ROW_NUMBER()
来查找每个部门中任职时间最长的雇员。
还有使用SELECT
来写CROSS APPLY
的另一种方法吗?
CREATE TABLE [dbo].[tblEmployee]
(
[ID] [INT] NOT NULL,
[DeptID] [TINYINT] NOT NULL,
[EmpName] [VARCHAR](100) NOT NULL,
[Tenure] [TINYINT] NOT NULL,
CONSTRAINT [PK_tblEmployee]
PRIMARY KEY CLUSTERED ([ID] ASC)
) ON [PRIMARY]
GO
INSERT INTO dbo.tblEmployee (ID, DeptID, EmpName, Tenure)
VALUES ('1', '1', 'John', 2),
('2', '1', 'Mary', 5),
('3', '2', 'Joe', 3),
('4', '3', 'Bill', 10),
('5', '2', 'Marilynn', 9),
('6', '3', 'Sue', 7);
SELECT
EmpName, DeptID, Tenure
FROM
(SELECT
EmpName, DeptID, Tenure,
ROW_NUMBER() OVER(PARTITION BY DeptID ORDER BY Tenure DESC) TenureRank
FROM
tblEmployee) e
WHERE
e.TenureRank = 1
ORDER BY
DeptID
编辑:我不希望将CTE用作SELECT
答案 0 :(得分:0)
等效的for (int i=0; i <= 3; i++)
{
Serial.print("I value:");Serial.print(i);
Serial.println();
Serial.print("guesser"); Serial.print(i+3-2*counter);
Serial.println();
Serial.print("digits");Serial.print(digits[i+3-(2*counter)]);
Serial.println();
if (digits[i+3-(2*counter)]==1)
{
digitalWrite(ledPins[i], HIGH);
Serial.print("THIS BULB LIT UP:");Serial.print(i);
}
else {
digitalWrite(ledPins[i], LOW);
}
counter=counter+1;
delay(1000);
}
为:
cross apply
您不想这样做,因为它的效率比select e.*, a.seqnum
from tblEmployee e cross apply
(select count(*) as seqnum
from tblEmployee e2
where e2.deptid = e.deptid and
(e2.tenure > e.tenure or
e2.tenure = e.tenure and e2.id >= e.id
)
) a;
低得多。请注意使用row_number()
进行比较以确保数字唯一。
答案 1 :(得分:0)
与扫描整个tblEmployee表相比,您可能有一个更好的部门ID来源:
SELECT a.*
FROM (SELECT DISTINCT DeptID FROM tblEmployee) d
CROSS APPLY (
SELECT TOP 1 EmpName, DeptID, Tenure
FROM tblEmployee e
WHERE e.DeptID = d.DeptID
ORDER BY Tenure DESC
) a
该特定示例不太可能支持APPLY
方法,因为您还需要设计源值。
在处理已经具有源数据的查询时,APPLY可能更有意义(例如,您也需要部门名称,因此自然而然地从想象中的tblDepartment
表开始)。当您需要从多个地方获取此类信息时(在一个查询中有多个APPLY比ROW_NUMBER()要容易得多),或者当APPLY操作本身是一个更复杂的子查询时,它也可以做得很好。 ,在几个表格中查找。
答案 2 :(得分:0)
您实际上可以执行此操作,而无需使用CROSS APPLY
或ROWNUM
。您可以创建一个派生表,列出每个部门的最大任职期,然后将其加入基本员工表。使用CTE,您的查询将如下所示:
WITH
DeptWithMaxTenure AS
(
SELECT DeptID, Max(Tenure) AS MaxTenure
FROM tblEmployee
GROUP BY DeptID
)
SELECT
tblEmployee.EmpName,
tblEmployee.DeptID,
tblEmployee.Tenure
FROM tblEmployee
INNER JOIN DeptWithMaxTenure ON
DeptWithMaxTenure.DeptID = tblEmployee.DeptID
AND DeptWithMaxTenure.MaxTenure = tblEmployee.Tenure
答案 3 :(得分:0)
我尝试过,它的速度是原始速度的4倍
SELECT A.EmpName, A.DeptID, A.Tenure FROM tblEmployee A
CROSS APPLY
(SELECT TOP 1 B.ID FROM tblEmployee B
WHERE B.DeptID = A.DeptID Order By Tenure Desc) CA
WHERE CA.ID = A.ID;