Як оптимізовано знайти third or nth
максимальну зарплату від зарплати table(EmpID,EmpName,EmpSalary)
?
Як оптимізовано знайти third or nth
максимальну зарплату від зарплати table(EmpID,EmpName,EmpSalary)
?
Відповіді:
Використовуйте 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
з основного запиту. Підзапит оцінюється щоразу, коли сканування основного запиту над рядком. Наприклад, якщо ми знайдемо третю найбільшу зарплату (N = 3) з (800, 1000, 700, 750), підзапит для 1-го ряду дорівнюватиме SELECT COUNT(DISTINCT(Emp2.Salary)) FROM Employee Emp2 WHERE Emp2.Salary > 800
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)
для Ex: 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)
для Ex: 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
);
Тут ви можете просто змінити n-е значення після обмеження LIMIT.
Ось у цьому підзапросі Виберіть EmpSalary з наказу працівника EmpSalary DESC Limit 3; повернула б топ-3 зарплати працівникам. З результату ми виберемо Мінімальну зарплату за допомогою команди MIN, щоб отримати третю ТОП-зарплату працівника.
Замініть 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
з основного запиту. Підзапит оцінюється щоразу, коли сканування основного запиту над рядком. Наприклад, якщо ми знайдемо третю найбільшу зарплату (N = 3) з (800, 1000, 700, 750), підзапит для 1-го ряду дорівнюватиме SELECT COUNT(DISTINCT(Emp2.Salary)) FROM Employee Emp2 WHERE Emp2.Salary > 800
0. Для 4-го значення зарплати (750) ... WHERE Emp2.Salary > 750
буде 2, або N -1, отже цей рядок буде повернуто.
Третя чи п'ята максимальна зарплата з таблиці заробітної плати без використання підпитів
select salary from salary
ORDER BY salary DESC
OFFSET N-1 ROWS
FETCH NEXT 1 ROWS ONLY
За 3-ту найвищу зарплату поставили 2 замість N-1
SELECT Salary,EmpName
FROM
(
SELECT Salary,EmpName,DENSE_RANK() OVER(ORDER BY Salary DESC) Rno from EMPLOYEE
) tbl
WHERE Rno=3
Наступний запит див. Для отримання n-ї найвищої зарплати. Таким чином ви отримуєте n-ту найвищу зарплату в MYSQL. Якщо ви хочете отримати 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 () НАДЕЖ (ЗАМОВЛЕННЯ EmpSalary DESC), щоб отримати звання без зв’язків, які ми можемо використовувати.
Наприклад, ми можемо отримати восьмий найвищий таким чином, або змінити @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. Я збираюся записувати різні запити, щоб дізнатися n-те найвище значення стовпця.
Я створив таблицю під назвою "Emloyee", запустивши сценарій нижче.
CREATE TABLE Employee([Eid] [float] NULL,[Ename] [nvarchar](255) NULL,[Basic_Sal] [float] NULL)
Тепер я збираюся вставити 8 рядків у цю таблицю, запустивши нижче оператор insert.
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 з наведеної таблиці за допомогою різних запитів. Я запустив запит нижче в студії управління, а нижче - результат.
select * from Employee order by Basic_Sal desc
На наведеному зображенні ми бачимо, що третя найвища основна зарплата становила б 8500. Я пишу 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 TOP 1 Salary as '3rd Highest Salary' from (SELECT DISTINCT TOP 3 Salary from Employee ORDER BY Salary DESC) a ORDER BY Salary ASC;
Я показую третю найвищу зарплату
SELECT MIN(COLUMN_NAME)
FROM (
SELECT DISTINCT TOP 3 COLUMN_NAME
FROM TABLE_NAME
ORDER BY
COLUMN_NAME DESC
) AS 'COLUMN_NAME'
- сьома найвища зарплата
select *
from (select lstName, salary, row_number() over( order by salary desc) as rn
from employee) tmp
where rn = 2
- (n-та -1) найвища зарплата
select *
from employee e1
where 1 = (select count(distinct salary)
from employee e2
where e2.Salary > e1.Salary )
Оптимізований спосіб: Замість запиту просто використовуйте ліміт.
select distinct salary from employee order by salary desc limit nth, 1;
Дивіться синтаксис обмеження тут http://www.mysqltutorial.org/mysql-limit.aspx
Отримати третє найвище значення з таблиці
SELECT * FROM tableName ORDER BY columnName DESC LIMIT 2, 1
За підпитом:
SELECT salary from
(SELECT rownum ID, EmpSalary salary from
(SELECT DISTINCT EmpSalary from salary_table order by EmpSalary DESC)
where ID = nth)
Спробуйте цей Запит
SELECT DISTINCT salary
FROM emp E WHERE
&no =(SELECT COUNT(DISTINCT salary)
FROM emp WHERE E.salary <= salary)
Поставте n = яке значення ви хочете
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 one one1
WHERE ( n ) = ( SELECT COUNT( one2.salary )
FROM one one2
WHERE one2.salary >= one1.salary
)
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-ту найвищу зарплату як кількість.
Спробуйте це ...
SELECT MAX(salary) FROM employee WHERE salary NOT IN (SELECT * FROM employee ORDERBY salary DESC LIMIT n-1)
ВИБІР * З ВІД (вибрати окрему заробітну плату від замовників на замовлення за заробітною платою DESC) межа 4,1;
Обмеження 4,1 означає залишити перші 4 ряди, а потім вибрати наступний.
Обмеження та кількість скорочень залежить від платформи, яку ви використовуєте.
Спробуйте це, воно спрацює.
ПРИМІТКА. Будь ласка, замініть OFFSET 3 у запиті будь-яким числом N-го числа
SELECT EmpName,EmpSalary
FROM SALARY
ORDER BY EmpSalary DESC
OFFSET 3 ROWS
FETCH NEXT 1 ROWS ONLY
Опис
ПОЛУЧАЙТЕ СЛЕДУЮЩИЙ 1 ТОЛЬКИ
повернути лише 1 ряд
ЗАМОВЛЕННЯ 3 РЯДИ
виключити перші 3 записи Тут ви можете будь-яке ціле число
Запити завжди займають більше часу:
використовуйте нижче запит, щоб отримати найвищі та найнижчі дані:
Найвищі дані: select *from business order by id desc limit 3,1;
Найнижчі дані: select *from business order by id asc limit 3,1;
Можна використовувати N на місці 3 для отримання n-го даних.