Мне любопытно, можно ли / как написать запрос, который возвращает максимальное значение каждой строки в таблице и индекс столбца, содержащего эту строку.

CREATE TABLE my_table (
id INT unsigned NOT NULL AUTO_INCREMENT,
field1 INT NOT NULL,
field2 INT NOT NULL,
PRIMARY KEY (id)
);

INSERT INTO my_table (field1, field2) VALUES
(5, 3),
(65, 89),
(4, 4)

Желаемый набор результатов запроса будет

id  max_val col_idx
--  ------- -------
1   5       2
2   89      3
3   4       2

(Я бы предпочел, чтобы связи по значению возвращали наименьший индекс столбца)

0
Jubbles 5 Апр 2014 в 02:37

3 ответа

Лучший ответ

Ты можешь это сделать

SELECT id , GREATEST(field1, field2) max_val ,
CASE WHEN field1 >= field2  THEN 2 ELSE 3 END col_idx
FROM my_table

Демо скрипки

2
M Khalid Junaid 4 Апр 2014 в 22:59

Это возвращает максимальное значение в каждой строке .. см. рабочий FIDDLE

SELECT
  IF (field1 >= field2, field1, field2) AS max_val,
  IF (field1 >= field2, 2, 3) AS my_index
FROM my_table
0
John Ruddell 4 Апр 2014 в 22:53

Нормализованный дизайн может выглядеть так ...

DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table 
(id INT unsigned 
,type INT NOT NULL
,val INT NOT NULL
,PRIMARY KEY (id,type)
);

INSERT INTO my_table VALUES
(1,1,5),
(1,2,3),
(2,1,65),
(2,2,89),
(3,1,4),
(3,2,4);

SELECT * FROM my_table;
+----+------+-----+
| id | type | val |
+----+------+-----+
|  1 |    1 |   5 |
|  1 |    2 |   3 |
|  2 |    1 |  65 |
|  2 |    2 |  89 |
|  3 |    1 |   4 |
|  3 |    2 |   4 |
+----+------+-----+

И поэтому...

SELECT x.* 
  FROM my_table x 
  LEFT 
  JOIN my_table y 
    ON y.id = x.id 
   AND (y.val > x.val OR (y.val = x.val AND y.type < x.type)) 
 WHERE y.id IS NULL;
+----+------+-----+
| id | type | val |
+----+------+-----+
|  1 |    1 |   5 |
|  2 |    2 |  89 |
|  3 |    1 |   4 |
+----+------+-----+

... или более современная и быстрая альтернатива.

0
Bryan Boettcher 7 Апр 2014 в 21:52