Выбор из базы данных, где одно поле имеет наибольшее числовое значение

Я уверен, что есть способ сделать это, но поскольку я все еще новичок в MySQL и PHP, я не могу понять это.

У меня есть таблица, где первый столбец (base_folder) представляет папку, в этой папке есть несколько изображений (sub_folder). Последнее поле (слой) представляет порядок изображения. Мне нужно получить максимальное число из столбца слоя, в котором base_folder, sub_folder, image_, image_type и view идентичны.

У кого-нибудь есть идеи, как это сделать?

Вот таблица:

+ ------------------------------------------------- ------------------------ +
| BASE_IMAGE |
+ ----- + ------------- + ------------ + ------------- + - -------- +-------+-------+
| id  | base_folder | вложенная папка | image       |image_type| посмотреть | слой |          
+ ----- + ------------- + ------------ + ------------- + ---------+-------+-------+
|  1  | CUP0001     |   F        | B_FF_0.png  | Б | FF | 0 |
+ ----- + ------------- + ------------ + ------------- + ---------+-------+-------+
|  2  | CUP0001     |   F        | B_FF_0.png  | Б |   FF  |   1   |
+-----+-------------+------------+-------------+ ---------+-------+-------+
|  3  | CUP0001     |   F        | B_FF_0.png  | Б |   FF  |   2   |
+-----+-------------+------------+-------------+ ---------+-------+-------+
|  4  | CUP0001     |   F        | B_FF_0.png  | М | FF | 0 |
+ ----- + ------------- + ------------ + ------------- + - -------- + ------- + ------- +

То, что я хотел бы получить, это "2", где base_folder['CUP0001'], sub_folder['F'], image['B_FF_0.png'], image_type['B'], view['FF'], слой ['2']

6 ответов

Решение

Прямой ответ на оригинальный вопрос:

SELECT MAX(layer)
  FROM Base_Image
 WHERE Base_Folder = 'CUP0001'
   AND Sub_Folder  = 'F'
   AND Image       = 'B_FF_0.png'
   AND Image_Type  = 'B'
   AND View        = 'FF';

Если вам нужен максимальный уровень для каждой комбинации из пяти полей, тогда вам нужно предложение GROUP BY, и вам также нужно выбрать идентифицирующие столбцы:

SELECT Base_Folder, Sub_Folder, Image, Image_Type, View, MAX(layer) AS MaxLayer
  FROM Base_Image
 GROUP BY Base_Folder, Sub_Folder, Image, Image_Type, View;

(Изъято: выглядит подозрительно, как если бы ваша таблица не была должным образом нормализована; есть хотя бы место для предположения, что комбинация Base_Folder, Sub_Folder, Image контролирует значения Image_Type и View. Однако показанный код будет работать независимо от того, является ли этот комментарий точный или нет.)


Если длинные комбинации не являются хорошими, [...] есть ли у вас предложение о лучшем подходе?

Это зависит от объема данных и от того, как вы собираетесь управлять данными. Это также зависит от того, какие части данных являются независимыми. Я хотел бы разделить таблицу на две части, хотя экстремальный вид может доходить до пяти таблиц:

  • Столбцы ImageFile (ID, Base_Folder, Sub_Folder, Image) с идентификатором первичного ключа и альтернативным ключом (уникальное ограничение) в (Base_Folder, Sub_Folder, Image).
  • ImageDetails (ID, ImageFileID, Image_Type, View, Layer, с идентификатором первичного ключа, альтернативным ключом (ImageFileID, Image_Type, View, Layer) и внешним ключом ImageFileID, ссылающимся на ImageFile.ID.

Альтернативный дизайн для ImageDetails избегает столбца ID и использует альтернативный ключ в качестве первичного ключа. Частично это зависит от того, будет ли что-либо еще ссылаться на строки в этой таблице.

Однако все зависит от того, что вы собираетесь делать и как на самом деле организованы данные (каковы функциональные зависимости в таблице, которую вы показываете). Экстремальный вид будет использовать: одну таблицу для базовых папок; затем будет таблица подпапок с идентификатором базовой папки и именем подпапки, собственным полем идентификатора, а затем будет таблица файлов изображений с собственным идентификатором, идентификатором подпапки и название изображения; затем была бы таблица типов изображений для каждого типа изображения каждого файла изображения (с его собственным идентификатором плюс FK); и так далее. Это сложнее вставлять строки; и каждая операция выбора, которая должна фильтровать, скажем, базовую папку и тип изображения, должна объединять множество таблиц. Это не должно быть медленным, но это усложняет SQL.

Использование GROUP BY и MAX агрегатный:

SELECT MAX(layer) AS max_layer, base_folder, sub_folder, image, image_type, view
       FROM base_image
       GROUP BY base_folder, sub_folder, image, image_type, view;
SELECT
      base_folder, sub_folder, image, image_type, view
    , MAX(layer)
FROM 
    BASE_IMAGE
GROUP BY
      base_folder, sub_folder, image, image_type, view
ORDER BY
      base_folder, sub_folder, image, image_type, view

Попробуйте это в своем заявлении SQL...

SELECT ........ ORDER BY 'layer' DESC LIMIT 1;

Первый подход, вероятно, будет использовать MAX() функция вместе с подзапросом. Однако это не очень эффективно.

Другое, лучшее решение - злоупотреблять ORDER BY оговорка, как это:

SELECT <your fields>
FROM `BASE_IMAGE`
WHERE <your conditions>
ORDER BY `layer` DESC
LIMIT 1

ORDER BY пункт вызывает самый большой id быть на вершине, а LIMIT Предложение обрезает все остальное, так что вы получите только самый верхний результат.

SELECT 
    MAX(layer)
FROM 
    table 
WHERE 
       image_type = 'B' AND 
       image = 'B_FF_0.png' AND 
       view = 'FF' AND 
       layer = '2' AND 
       sub_folder = 'F'
Другие вопросы по тегам