Подтвердить что ты не робот

Есть ли что-то эквивалентное argmax в SQL?

В более общем смысле: существует ли функция, которая позволит мне найти всю строку, где значение в столбце X является максимальным значением столбца?

4b9b3361

Ответ 1

Не определенная функция, нет.

Существует множество способов написания запроса в зависимости от потребностей и функциональности, поддерживаемой базой данных.

Подзапрос:

Этот подход позволяет возвращать более одной строки, если какое-либо значение имеет одно и то же значение:

SELECT x.*
  FROM YOUR_TABLE x
 WHERE x.column = (SELECT MAX(y.column)
                     FROM YOUR_TABLE y)

Self Join:

Этот подход позволяет возвращать более одной строки, если какое-либо значение имеет одно и то же значение:

SELECT x.*
  FROM YOUR_TABLE x
  JOIN (SELECT MAX(t.column) AS max_col
          FROM YOUR_TABLE t) y ON y.max_col = x.column

LIMIT/TOP:

SQL Server поддерживает TOP:

  SELECT TOP 1 
         x.*
    FROM YOUR_TABLE x
ORDER BY x.column DESC

Поддержка MySQL и PostgreSQL LIMIT:

  SELECT x.*
    FROM YOUR_TABLE x
ORDER BY x.column DESC
   LIMIT 1

Аналитика - ROW_NUMBER():

Это приведет к возврату одной строки и может быть настроено для обеспечения наивысшего (или самого низкого) значения для каждой группы. Однако эта функциональность - Oracle 9i +, SQL Server 2005+ и PostgreSQL 8.4 +.

SELECT x.*
  FROM (SELECT y.*,
               ROW_NUMBER() OVER (ORDER BY y.column DESC) AS rank
          FROM YOUR_TABLE y) x
 WHERE x.rank = 1 

Аналитика - DENSE_RANK():

Это может возвращать несколько строк, если они имеют одно и то же значение и могут быть настроены для обеспечения наивысшего (или самого низкого) значения для каждой группы. Однако эта функциональность - Oracle 9i +, SQL Server 2005+ и PostgreSQL 8.4 +.

SELECT x.*
  FROM (SELECT y.*,
               DENSE_RANK() OVER (ORDER BY y.column DESC) AS rank
          FROM YOUR_TABLE y) x
 WHERE x.rank = 1 

Ответ 2

SELECT *
FROM mytable
WHERE mycolumn = (
  SELECT MAX(mycolumn) FROM mytable
)

Ответ 3

Если я правильно читаю ваш вопрос, следующий запрос должен сделать это (предполагая, что имена наших столбцов - это a, b и c и что a - это столбец, который мы максимизируем):

select a,b,c from table where a=(select max(a) from table);

Конечно, если у вас есть несколько строк, где столбец a достигает своего максимума, вы получите больше одной строки из запроса. Если вы хотите получить уникальную строку назад, вы можете добавить что-то вроде "order by b, c limit 1" или использовать другой способ ранжирования строк, в которых a достигает максимального значения.

Ответ 4

SELECT
    *
FROM
    YourTable
WHERE
    YourColum = (SELECT MAX(YourColumn) FROM YourTable)

Ответ 5

Поскольку имя таблицы и имя столбца указаны, я оставляю их как наполнители. Запрос будет выглядеть следующим образом:

SELECT *
  FROM <YOUR_TABLE>
WHERE <YOUR_COLUMN_NAME> = (SELECT MAX(<YOUR_COLUMN_NAME>)
  FROM <YOUR_TABLE>)

Ответ 6

Я думаю, что следующее будет выбирать каждую строку, где значение в столбце X равно максимальному значению столбца X:

SELECT * FROM [table] WHERE [Column X]=SELECT (MAX([Column X]) FROM [table])

Ответ 7

Не так давно я разговаривал с моим другом, и мы обсудили немного другую, но довольно практическую проблему, о том, чтобы разделить "таблицу" на группы, а затем найти argmax/argmin для каждой полученной нами ощупывания. В частности, предположим, что у нас есть таблица, в которой мы сохраняем все версии некоторых объектов (что означает историю всех сущностей, а активная сущность - самая последняя в ее вершине (история)), так как мы можем наиболее эффективно выбирать только активные записи из этой таблицы (точнее - разделить на группы по entity_id (не row_id) и найти argmax в каждом столбце по столбцу версии). Так что, поскольку одна из моих первых мыслей о том, "как исследовать эту проблему", была ключевой фразой "oracle sql argmax OR argmin". Я размещаю свой комментарий здесь.

Как говорит мой друг, они используют ключевое слово [PARTITION BY] [PARTITION-BY] для своих средств, и, как я могу видеть из fetch-the-row-which-has-the-max-value-for-a-column и getting-values-relating-to-the-max-and-min-rows-in-oracle есть два варианта использования DENSE_RANK с "OVER (ORDER BY...)", а затем привязать этот ранг к 1 (как описано здесь и в "fetch-the-row-which-has-the-max-value-for-a-column ") или используйте что-то вроде "max (version) over (partition by entity_id/not row_id/) max_version", а затем связали "version = max_version" в том случае, как описано в "getting-values-relating-to-the-max-and-min-rows-in-oracle "(" fetch-the-row-which-has-the-max-value-for-a-column"), и мой друг говорит, что они предпочитают точно второй подход, как я понял, потому что он может потребовать меньше вычислений для каждой группы, поскольку он только находит максимальное значение и не должен полностью сортировать каждую группу, с другой стороны, если будет больше одна запись с таким же максимальным значением, этот запрос будет выбирать не единственную произвольную выбранную строку с максимальным значением "столбца заказа" (в нашем случае), но все строки (из группы), которые имеют это максимальное значение (так что может возвращать Argmax - не только как одну строку, но и как набор строк, где это достигается).

Кроме того, поскольку я понял, что ключевое слово [KEEP] [KEEP] [LAST]/[FIRST] в [Oracle SQL] [oracle-sql-ref] нацелено на использование варианта использования argmin/armax, в обоих вариантах - с [GROUP BY] [GROUP-BY] или [PARTITION BY] [PARTITION-BY], но поскольку они предполагают, что результат Argmax и Argmin может содержать несколько строк (не только одна строка), вы не можете просто выбрать "эта строка" использует [KEEP]... [FIRST]/[KEEP]... [LAST], вместо этого вы используете некоторую функцию [агрегации] [Oracle-Sql-Aggregate-Functions], чтобы "извлечь" некоторые значение из "этих строк" ​​(строки Argmax), например (из [Oracle doc] [FIRST-Analytic-Example])

MAX(salary) KEEP (DENSE_RANK LAST ORDER BY commission_pct)
  OVER (PARTITION BY department_id) "Best"

где

KEEP (DENSE_RANK LAST ORDER BY commission_pct) OVER (PARTITION BY department_id)

предоставляет вам Argmax в виде набора строк (через группу department_id, используя комиссию_pct в качестве критерия) и

MAX(salary)

предоставляет вам окончательную агрегацию по этим Argmax (возможно, многочисленным) строкам. ([Выбрать строку с максимальным значением] [Select-row-with-Max-Value] - обсуждение послужило отправной точкой для меня, чтобы понять это).

Вот несколько справочных статей.

oracle-sql-ref
Oracle-Sql-Агрегатные функции
KEEP
FIRST
FIRST-Analytic-Example
LAST
Select-row-with-Max-Value
GROUP-BY
PARTITION-BY
ORDER-BY-Analysis

SQL-функции/query_partition_clause

DENSE_RANK
MAX
ROW_NUMBER


Вот несколько свободно цитируемых фрагментов о вещах, упомянутых выше.

используя [ROW_NUMBER] с [ORDER BY] [ORDER-BY-Analysis] и [PARTITION BY] [PARTITION-BY]

select row_id, entity_id, version, entity_value_1, entity_value_2
  from (select row_id, entity_id, version, entity_value_1, entity_value_2, 
          row_number()
            over (partition by entity_id order by version desc) as rank
        from Entities) as r
  where r.rank=1

с помощью [MAX] с [PARTITION BY] [PARTITION-BY]

select row_id, entity_id, version, max_version, entity_value_1, entity_value_2
  from (select row_id, entity_id, version, entity_value_1, entity_value_2, 
          max(version) over (partition by entity_id) as max_version
        from Entities) as r
  where r.version=r.max_version

с помощью [KEEP] [KEEP] [LAST]/[FIRST] для подавления возможности нескольких строк с тем же именем entity_id и версией в результате (среди строк Argmax, выбирающих уникальный с максимальным значением row_id)

SELECT row_id, entity_id, version, max_version, entity_value_1, entity_value_2
  FROM (SELECT 
          row_id, entity_id, version, entity_value_1, entity_value_2, 
          MAX(row_id) 
            KEEP (DENSE_RANK LAST ORDER BY version ASC)
            OVER (PARTITION BY entity_id) 
            AS row_id_for_max_version
        FROM Entities) as r
  WHERE r.row_id=r.row_id_for_max_version

Ответ 8

- я принял имя таблицы = max_search и column_name: A, B и C

и значения в таблице

A B C 10 20 30 60 40 50 80 90 70

Query: -

SELECT (ДЕЛО   КОГДА A > B И A > C THEN 'A'   КОГДА B > A И B > C THEN 'B'   КОГДА C > B И C > A THEN 'C' END) AS "Column_Name", наибольший (A, B, C) AS Max_Value FROM max_search;

Вывод: - Column_Name Max_Value C 30 A 60 B 90