Выбор из базы данных, где одно поле имеет наибольшее числовое значение
Я уверен, что есть способ сделать это, но поскольку я все еще новичок в 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'