آشنایی با Window Function ها در SQL Server بخش چهارم
نویسنده: فرهاد فرهمندخواه
تاریخ: ۱۳۹۱/۱۰/۰۳ ۲۳:۳۰
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
FIRST_VALUE ( [scalar_expression )
OVER ( [ partition_by_clause ] order_by_clause [ rows_range_clause ] )
شرح Syntax:
1- Scalar_expression: مقدار آن میتواند نام یک فیلد یا Subquery باشد.
2- Over : در بخش اول بطور مفصل آن را بررسی نمودیم.
قبل از بررسی تابع First_Value،ابتدا Script زیر را اجرا نمایید، که شامل یک جدول و درج چند رکورد در آن است.
Create Table Test_First_Last_Value (SalesOrderID int not null, SalesOrderDetailID int not null , OrderQty smallint not null); GO Insert Into Test_First_Last_Value Values (43662,49,1),(43662,50,3),(43662,51,1), (43663,52,1),(43664,53,1),(43664,54,1), (43667,77,3),(43667,78,1),(43667,79,1), (43667,80,1),(43668,81,3),(43669,110,1), (43670,111,1),(43670,112,2),(43670,113,2), (43670,114,1),(43671,115,1),(43671,116,2)
مثال: ابتدا Scriptی ایجاد مینماییم،بطوریکه جدول Test_Firts_Last_Value را براساس فیلد SalesOrderID گروه بندی نموده و اولین مقدار فیلد SalesOrderDetailID در هرگروه را مشخص نماید.
SELECT s.SalesOrderID,s.SalesOrderDetailID,s.OrderQty, FIRST_VALUE(SalesOrderDetailID) OVER (PARTITION BY SalesOrderID ORDER BY SalesOrderDetailID) FstValue FROM Test_First_Last_Value s WHERE SalesOrderID IN (43670, 43669, 43667, 43663) ORDER BY s.SalesOrderID,s.SalesOrderDetailID,s.OrderQty
خروجی:
مطابق Script چهار گروه در خروجی ایجاد شده است و در فیلد FstValue ، اولین مقدار هر گروه نمایش داده میشود. اگر بخشهای قبلی Window Functionها را مطالعه کرده باشید، تحلیل این تابع کار بسیار ساده ای است.
- Last_Value
این تابع نیز در نسخه SQL Server 2012 ارائه گردیده است. و آخرین مقدار از یک مجموعه مقادیر را بر میگرداند، به عبارتی فانکشن Last_Value عکس فانکشن First_Value عمل مینماید و Syntax آن به شرح ذیل میباشد:LAST_VALUE ( [scalar_expression ) OVER ( [ partition_by_clause ] order_by_clause rows_range_clause )شرح Syntax تابع Last_Value شبیه به تابع First_Value میباشد.
مثال: همانند مثال قبل Scriptی ایجاد مینماییم،بطوریکه جدول Test_Firts_Last_Value را براساس فیلد SalesOrderID گروه بندی نموده و آخرین مقدار فیلد SalesOrderDetailID در هرگروه را مشخص نماید.SELECT s.SalesOrderID,s.SalesOrderDetailID,s.OrderQty, LAST_VALUE(SalesOrderDetailID) OVER (PARTITION BY SalesOrderID ORDER BY SalesOrderDetailID RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) LstValue FROM Test_First_Last_Value s WHERE SalesOrderID IN (43670, 43669, 43667, 43663) ORDER BY s.SalesOrderID,s.SalesOrderDetailID,s.OrderQtyخروجی:
خروجی جدول،به چهار گروه تقسیم،و آخرین مقدار هر گروه،در فیلد LstValue نمایش داده شده است. در این مثال نیز تحلیلی نخواهیم داشت، چون فرض بر آن است که بخشهای قبلی را مطالعه نموده ایم.
موفق باشید.
SELECT s.SalesOrderID,s.SalesOrderDetailID,s.OrderQty,
MIN(SalesOrderDetailID) OVER (PARTITION BY SalesOrderID) FstValue
FROM Test_First_Last_Value s
WHERE SalesOrderID IN (43670, 43669, 43667, 43663)
ORDER BY s.SalesOrderID,s.SalesOrderDetailID,s.OrderQty
CREATE TABLE Employees (
EmployeeId INT IDENTITY PRIMARY KEY,
Name VARCHAR(50),
HireDate DATE NOT NULL,
Salary INT NOT NULL
)
GO
INSERT INTO Employees (Name, HireDate, Salary)
VALUES
('Alice', '2011-01-01', 20000),
('Brent', '2011-01-15', 19000),
('Carlos', '2011-02-01', 22000),
('Donna', '2011-03-01', 25000),
('Evan', '2011-04-01', 18500)
GO
Select EmployeeId,Name,Salary,HireDate,
First_VALUE(HireDate) OVER(ORDER BY Salary RANGE BETWEEN UNBOUNDED PRECEDING
AND UNBOUNDED FOLLOWING) AS First,
Min(HireDate) OVER(ORDER BY Salary
RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS Min
FROM Employees
ORDER BY EmployeeId
GO
Select EmployeeId,Name,Salary,HireDate,
First_VALUE(HireDate) OVER(ORDER BY Salary RANGE BETWEEN UNBOUNDED PRECEDING
AND UNBOUNDED FOLLOWING) AS First,
D.HireDate AS older_method
FROM Employees
CROSS APPLY (SELECT TOP 1 HireDate
FROM Employees
--WHERE E1.EmployeeId = E2.EmployeeId
ORDER BY Salary ASC) AS D
ORDER BY EmployeeId;
SELECT s.SalesOrderID,s.SalesOrderDetailID,s.OrderQty,
LAST_VALUE(SalesOrderDetailID) OVER (PARTITION BY SalesOrderID
ORDER BY SalesOrderDetailID) LstValue
FROM Test_First_Last_Value s
WHERE SalesOrderID IN (43670, 43669, 43667, 43663)
ORDER BY s.SalesOrderID,s.SalesOrderDetailID,s.OrderQty
SELECT s.SalesOrderID,s.SalesOrderDetailID,s.OrderQty,
FITST_VALUE(SalesOrderDetailID) OVER (PARTITION BY SalesOrderID
ORDER BY SalesOrderDetailID DESC) FstValue
FROM Test_First_Last_Value s
WHERE SalesOrderID IN (43670, 43669, 43667, 43663)
ORDER BY s.SalesOrderID,s.SalesOrderDetailID,s.OrderQty
RANGE UNBOUNDED PRECEDING AND CURRENT ROW
SELECT s.SalesOrderID,s.SalesOrderDetailID,s.OrderQty,
FIRST_VALUE(SalesOrderDetailID) OVER (PARTITION BY SalesOrderID
ORDER BY SalesOrderDetailID RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) LstValue
FROM Test_First_Last_Value s
WHERE SalesOrderID IN (43670, 43669, 43667, 43663)
ORDER BY s.SalesOrderID,s.SalesOrderDetailID,s.OrderQty
SELECT s.SalesOrderID,s.SalesOrderDetailID,s.OrderQty,
LAST_VALUE(SalesOrderDetailID) OVER (PARTITION BY SalesOrderID
ORDER BY SalesOrderDetailID DESC RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) LstValue
FROM Test_First_Last_Value s
WHERE SalesOrderID IN (43670, 43669, 43667, 43663)
ORDER BY s.SalesOrderID,s.SalesOrderDetailID,s.OrderQty