Ето пет опции за използване на SQL за връщане само на онези редове, които имат минималната стойност в тяхната група.
Тези примери работят в повечето основни RDBMS, включително MySQL, MariaDB, Oracle, PostgreSQL, SQLite и SQL Server.
Примерни данни
Да предположим, че имаме таблица със следните данни:
ИЗБЕРЕТЕ * ОТ Gameshow;
Резултат:
<пред>+--------------+-------+-------+| Състезател | Игра | Резултат ||--------------+-------+--------|| Фей | 1 | 85 || Фей | 2 | 50 || Фей | 3 | 63 || Реактивен | 1 | 31 || Реактивен | 2 | 40 || Реактивен | 3 | 51 || Спайк | 1 | 25 || Спайк | 2 | 27 || Спайк | 3 | 15 |+--------------+-------+-------+И да предположим, че искаме да получим най-ниския резултат за всеки състезател.
Опция 1
Бърза и лесна опция е да създадете заявка с SQL GROUP BY
клауза:
ИЗБЕРЕТЕ състезател, MIN (резултат) КАТО Мин.резултатFROM GameshowGROUP BY ContestantORDER BY Contestant;
Резултат:
+--------------+-----------+| Състезател | MinScore ||--------------+-----------|| Фей | 50 || Реактивен | 31 || Спайк | 15 |+--------------+-----------+
Опция 2
Ако искаме да включим играта, която всеки състезател играе, за да получи минимален резултат, тогава един от начините да направим това е да използваме корелирана подзаявка като тази:
ИЗБЕРЕТЕ състезател, игра, резултат ОТ Gameshow g1WHERE Резултат =( SELECT MIN( g2.Score ) ОТ Gameshow g2 WHERE g1.Contestant =g2.Contestant )ПОРЪЧКА ПО Състезател;
Резултат:
<пред>+--------------+-------+-------+| Състезател | Игра | Резултат ||--------------+-------+--------|| Фей | 2 | 50 || Реактивен | 1 | 31 || Спайк | 3 | 15 |+--------------+-------+-------+Корелираните подзаявки се отнасят до една или повече колони извън подзаявката. Корелираните подзаявки могат да бъдат неефективни, главно поради факта, че подзаявката се изпълнява многократно, веднъж за всеки ред, който може да бъде избран от външната заявка. Корелираните подзаявки са известни също като повтарящи се подзаявки.
Опция 3
Като алтернатива можем да използваме некорелирана подзаявка като тази:
ИЗБЕРЕТЕ g1.Contestant, g1.Game, g1.ScoreFROM Gameshow g1JOIN ( SELECT Contestant, MIN( Score) КАТО Резултат ОТ Gameshow ГРУПА ПО Състезател) AS g2 ON g1.Contestant =g2.Contestant И g1.Score =g2.ScoreORDER BY Contestant ASC;
Резултат:
<пред>+--------------+-------+-------+| Състезател | Игра | Резултат ||--------------+-------+--------|| Фей | 2 | 50 || Реактивен | 1 | 31 || Спайк | 3 | 15 |+--------------+-------+-------+Некорелираните подзаявки не зависят от външната заявка за тяхното изпълнение. Те могат да се изпълняват напълно независимо от външната заявка.
В Oracle трябва да премахнем AS
при деклариране на псевдоними на колоните:
ИЗБЕРЕТЕ g1.Contestant, g1.Game, g1.ScoreFROM Gameshow g1JOIN ( SELECT Contestant, MIN( Score) Резултат ОТ Gameshow ГРУПА ПО Състезател) g2 ON g1.Contestant =g2.Contestant И g1.Score =g2 .ScoreORDER BY Contestant ASC;
Опция 4
Друг начин за извличане на редове с минимална стойност в дадена колона е да използвате LEFT JOIN
, като това:
ИЗБЕРЕТЕ g1.Contestant, g1.Game, g1.ScoreFROM Gameshow g1LEFT JOIN Gameshow g2 ON g1.Contestant =g2.Contestant AND g1.Score> g2.ScoreWHERE g2.Contestant Е НУЛЕВ ОРД ОТ g1.Contestant ASC;
Резултат:
<пред>+--------------+-------+-------+| Състезател | Игра | Резултат ||--------------+-------+--------|| Фей | 2 | 50 || Реактивен | 1 | 31 || Спайк | 3 | 15 |+--------------+-------+-------+Опция 5
Друг начин да го направите е като използвате общ табличен израз с функция прозорец:
С cte AS ( ИЗБЕРЕТЕ състезател, игра, резултат, RANK() НАД ( РАЗДЕЛЯНЕ ПО състезател ПОРЪЧКА ПО Резултат ASC ) КАТО r ОТ Gameshow)ИЗБЕРЕТЕ Състезател, игра, РезултатFROM cteWHERE r =1 ПОРЪЧКА ПО Състезател ASC;код>
Резултат:
<пред>+--------------+-------+-------+| Състезател | Игра | Резултат ||--------------+-------+--------|| Фей | 2 | 50 || Реактивен | 1 | 31 || Спайк | 3 | 15 |+--------------+-------+-------+