Една от новите функции в PostgreSQL 13 е SQL-стандартът WITH TIES
клауза за използване с LIMIT
— или, както стандартът нарича това, FETCH FIRST n ROWS
. Благодарности се дължат на Surafel Temesgen като първоначален автор на пластир; Томас Вондра и Ваши наистина за някои допълнителни корекции на кода; и рецензенти Андрю Гиърт и Ерик Райкерс. Можете да прегледате съобщението за записване.
Равенствата са много често при класирането на нещата; например, в състезание за каукус може да имате много равенства и със сигурност не искате да лишавате участниците от техните награди! Какво WITH TIES
прави е доста просто:добавя всеки следващ ред или редове към вашия набор от резултати, ако те се класират, равен на последния върнат ред според LIMIT
клауза, съгласно ORDER BY
клауза.
Ако искате само двамата служители с най-висока заплата, можете да направите това:
SELECT * FROM employees ORDER BY salary DESC LIMIT 2;
име | заплата | отдел |
---|---|---|
Алисия | 1600 | инженерство |
Оруга | 1500 | маркетинг |
Така че те сърби да знаеш заплатата на следващия човек? Ами ако тя съвпада с Оруга и просто е била пропусната по чиста случайност или лош късмет? Това може да се случи, както добре знаете; и за щастие, WITH TIES
сега е там, за да спаси деня. (Обърнете внимание, че в действителност ние не обработваме WITH TIES
в LIMIT
клауза като такава. Трябва да използвате FETCH FIRST
синтаксис, който е задължителен от стандартите, за да може да се използва WITH TIES
.)
SELECT * FROM employees ORDER BY salary DESC FETCH FIRST 2 ROWS WITH TIES;
име | заплата | отдел |
---|---|---|
Алисия | 1600 | инженерство |
Оруга | 1500 | продажби |
Конехо Бланко | 1500 | маркетинг |
Там! Белият заек има да бъде включен в списъка и сега е.
Няколко бележки, преди да полудеете твърде много. LIMIT
(или по-точно FETCH FIRST
) вече не обещава да върне точно посочения от вас брой редове. Можете да получите два или двадесет допълнителни реда или 100 пъти толкова редове, колкото сте поискали. Наред с други неща, това означава, че трябва да следите колко реда сте виждали досега, ако ранжирате резултатите. В горното имате три реда, така че за следващата страница пропускате толкова много, като добавите правилния OFFSET
клауза:
SELECT * FROM employees
ORDER BY salary DESC
FETCH FIRST 2 ROWS WITH TIES
OFFSET 3;
име | заплата | отдел |
---|---|---|
Falsa Tortuga | 1400 | маркетинг |
Дукеса | 1300 | продажби |
Liebre de Marzo | 1300 | инженерство |
Отново получихме три, а не само две, които поискахме. Така че за следващата страница ще трябва да пропуснете шест. И така нататък. Уверете се, че имате достатъчно напръстници за всички.
Другото нещо, което трябва да имате предвид, е, че трябва да се уверите, че използвате само ORDER BY
клауза, която отговаря на WITH TIES
клауза; ако искате, да речем, редовете на една и съща заплата да бъдат подредени по име, ще трябва да използвате подзаявка. В противен случай разграничението в имената би разрешило равенството на заплатата, така че следващият ред няма да бъде включен. Например:
SELECT * FROM (
SELECT * FROM employees
ORDER BY salary DESC
FETCH FIRST 2 ROWS WITH TIES) AS subq
ORDER BY salary DESC, name;
Тази функция е там, за да ви помогне да покажете всички редове с една и съща стойност — тя ви позволява да не дискриминирате някои редове с еднаква стойност въз основа единствено на физическото местоположение в таблицата.
Приятно пагиниране!