回答:
使用ROW_NUMBER
(単一をしたい場合)またはDENSE_RANK
(すべての関連行の):
WITH CTE AS
(
SELECT EmpID, EmpName, EmpSalary,
RN = ROW_NUMBER() OVER (ORDER BY EmpSalary DESC)
FROM dbo.Salary
)
SELECT EmpID, EmpName, EmpSalary
FROM CTE
WHERE RN = @NthRow
EmpSalary
列にインデックスがありません。また、何と比べて減った?このROW_NUMBER
アプローチの利点は、を使用できること..OVER(PARTITION BY GroupColumn OrderBy OrderColumn)
です。したがって、これを使用してグループを取得できますが、その列には引き続きアクセスできます。
行番号:
SELECT Salary,EmpName
FROM
(
SELECT Salary,EmpName,ROW_NUMBER() OVER(ORDER BY Salary) As RowNum
FROM EMPLOYEE
) As A
WHERE A.RowNum IN (2,3)
サブクエリ:
SELECT *
FROM Employee Emp1
WHERE (N-1) = (
SELECT COUNT(DISTINCT(Emp2.Salary))
FROM Employee Emp2
WHERE Emp2.Salary > Emp1.Salary
)
上位のキーワード:
SELECT TOP 1 salary
FROM (
SELECT DISTINCT TOP n salary
FROM employee
ORDER BY salary DESC
) a
ORDER BY salary
... WHERE (N-1) = (Subquery)...
機能するのかを理解することが重要です。サブクエリは、メインクエリからWHERE
使用さEmp1
れるため、相関クエリです。サブクエリは、メインクエリが行をスキャンするたびに評価されます。SELECT COUNT(DISTINCT(Emp2.Salary)) FROM Employee Emp2 WHERE Emp2.Salary > 800
たとえば、(800、1000、700、750)から3番目に大きい給与(N = 3)を見つける場合、1行目のサブクエリは0になります。4番目の給与値(750)... WHERE Emp2.Salary > 750
は2またはNになります-1、したがってこの行が返されます。
最適化の方法が必要な場合は、TOP
キーワードを使用することを意味します。したがって、n番目の最大および最小給与クエリは次のようになりますが、クエリは集計関数名を使用すると逆順のようにトリッキーに見えます。
N最大給与:
SELECT MIN(EmpSalary)
FROM Salary
WHERE EmpSalary IN(SELECT TOP N EmpSalary FROM Salary ORDER BY EmpSalary DESC)
例:3最高給与:
SELECT MIN(EmpSalary)
FROM Salary
WHERE EmpSalary IN(SELECT TOP 3 EmpSalary FROM Salary ORDER BY EmpSalary DESC)
Nの最低給与:
SELECT MAX(EmpSalary)
FROM Salary
WHERE EmpSalary IN(SELECT TOP N EmpSalary FROM Salary ORDER BY EmpSalary ASC)
例:3の最低給与:
SELECT MAX(EmpSalary)
FROM Salary
WHERE EmpSalary IN(SELECT TOP 3 EmpSalary FROM Salary ORDER BY EmpSalary ASC)
サブクエリを使用する場合は単純すぎます。
SELECT MIN(EmpSalary) from (
SELECT EmpSalary from Employee ORDER BY EmpSalary DESC LIMIT 3
);
ここでは、LIMIT制約の後のn番目の値を変更できます。
ここでは、このサブクエリで、EmpSalary DESC Limit 3によって従業員の注文からEmpSalaryを選択します。従業員のトップ3の給与を返します。結果から、MINコマンドを使用して最低給与を選択し、従業員の3番目のTOP給与を取得します。
Nを最大数に置き換えます
SELECT *
FROM Employee Emp1
WHERE (N-1) = (
SELECT COUNT(DISTINCT(Emp2.Salary))
FROM Employee Emp2
WHERE Emp2.Salary > Emp1.Salary)
説明
上記のクエリは、これまでにそのようなものを見たことがない場合、非常に混乱する可能性があります。内部クエリ(相関クエリ)は、内部クエリ(サブクエリ)が外部クエリ(この場合はEmp1テーブル)の値を使用するためです)はWHERE句です。
そしてソース
... WHERE (N-1) = (Subquery)...
機能するのかを理解することが重要です。サブクエリは、メインクエリからWHERE
使用さEmp1
れるため、相関クエリです。サブクエリは、メインクエリが行をスキャンするたびに評価されます。SELECT COUNT(DISTINCT(Emp2.Salary)) FROM Employee Emp2 WHERE Emp2.Salary > 800
たとえば、(800、1000、700、750)から3番目に大きい給与(N = 3)を見つける場合、1行目のサブクエリは0になります。4番目の給与値(750)... WHERE Emp2.Salary > 750
は2またはNになります-1、したがってこの行が返されます。
サブクエリを使用せずに給与テーブルから3番目またはn番目の最大給与
select salary from salary
ORDER BY salary DESC
OFFSET N-1 ROWS
FETCH NEXT 1 ROWS ONLY
3番目に高い給与の場合、N-1の代わりに2を入れます。
SELECT Salary,EmpName
FROM
(
SELECT Salary,EmpName,DENSE_RANK() OVER(ORDER BY Salary DESC) Rno from EMPLOYEE
) tbl
WHERE Rno=3
n番目に高い給与を取得するには、次のクエリを参照してください。このようにして、MYSQLでn番目に高い給与を得ます。n番目に低い給与を取得する場合は、クエリでDESCをASCに置き換える必要があります。
SELECT EmpSalary
FROM salary_table
GROUP BY EmpSalary
ORDER BY EmpSalary DESC LIMIT n-1, 1;
方法1:
SELECT TOP 1 salary FROM (
SELECT TOP 3 salary
FROM employees
ORDER BY salary DESC) AS emp
ORDER BY salary ASC
方法2:
Select EmpName,salary from
(
select EmpName,salary ,Row_Number() over(order by salary desc) as rowid
from EmpTbl)
as a where rowid=3
2008年には、ROW_NUMBER()OVER(ORDER BY EmpSalary DESC)を使用して、使用できる結合なしのランクを取得できます。
たとえば、この方法で8番目に高い値を取得したり、@ Nを別の値に変更したり、必要に応じて関数のパラメーターとして使用したりできます。
DECLARE @N INT = 8;
WITH rankedSalaries AS
(
SELECT
EmpID
,EmpName
,EmpSalary,
,RN = ROW_NUMBER() OVER (ORDER BY EmpSalary DESC)
FROM salary
)
SELECT
EmpID
,EmpName
,EmpSalary
FROM rankedSalaries
WHERE RN = @N;
SQL Server 2012では、ご存知かもしれませんが、これはLAG()を使用してより直感的に実行されます。
declare @maxNthSal as nvarchar(20)
SELECT TOP 3 @maxNthSal=GRN_NAME FROM GRN_HDR ORDER BY GRN_NAME DESC
print @maxNthSal
これは、SQLインタビューでよくある質問の1つです。列のn番目に高い値を見つけるために、さまざまなクエリを書き留めます。
以下のスクリプトを実行して、「Emloyee」という名前のテーブルを作成しました。
CREATE TABLE Employee([Eid] [float] NULL,[Ename] [nvarchar](255) NULL,[Basic_Sal] [float] NULL)
次に、以下のinsertステートメントを実行して、このテーブルに8行を挿入します。
insert into Employee values(1,'Neeraj',45000)
insert into Employee values(2,'Ankit',5000)
insert into Employee values(3,'Akshay',6000)
insert into Employee values(4,'Ramesh',7600)
insert into Employee values(5,'Vikas',4000)
insert into Employee values(7,'Neha',8500)
insert into Employee values(8,'Shivika',4500)
insert into Employee values(9,'Tarun',9500)
次に、さまざまなクエリを使用して、上の表から3番目に高いBasic_salを見つけます。以下のクエリをManagement Studioで実行したところ、結果が表示されました。
select * from Employee order by Basic_Sal desc
上記の画像から、3番目に高い基本給が8500になることがわかります。同じことを行う3つの異なる方法を書いています。以下の3つのクエリをすべて実行すると、同じ結果、つまり8500が得られます。
最初の方法:-行番号関数の使用
select Ename,Basic_sal
from(
select Ename,Basic_Sal,ROW_NUMBER() over (order by Basic_Sal desc) as rowid from Employee
)A
where rowid=2
最適化された方法:サブクエリの代わりに制限を使用します。
select distinct salary from employee order by salary desc limit nth, 1;
こちらの制限構文をご覧くださいhttp://www.mysqltutorial.org/mysql-limit.aspx
テーブルから3番目に高い値を取得するには
SELECT * FROM tableName ORDER BY columnName DESC LIMIT 2, 1
set @n = $n
SELECT a.* FROM ( select a.* , @rn = @rn+1 from EMPLOYEE order by a.EmpSalary desc ) As a where rn = @n
select * from employee order by salary desc;
+------+------+------+-----------+
| id | name | age | salary |
+------+------+------+-----------+
| 5 | AJ | 20 | 100000.00 |
| 4 | Ajay | 25 | 80000.00 |
| 2 | ASM | 28 | 50000.00 |
| 3 | AM | 22 | 50000.00 |
| 1 | AJ | 24 | 30000.00 |
| 6 | Riu | 20 | 20000.00 |
+------+------+------+-----------+
select distinct salary from employee e1 where (n) = (select count( distinct(salary) ) from employee e2 where e1.salary<=e2.salary);
nを、数値としてn番目に高い給与に置き換えます。
注:クエリのオフセット3をN番目の整数に置き換えてください
SELECT EmpName,EmpSalary
FROM SALARY
ORDER BY EmpSalary DESC
OFFSET 3 ROWS
FETCH NEXT 1 ROWS ONLY
説明
次の1行のみフェッチ
1行のみを返す
オフセット3行
最初の3つのレコードを除外するここでは、任意の整数を使用できます