|
Тема
|
Проблем с MIN() и MAX()
|
|
Автор | Cтyдeнт (Нерегистриран) |
Публикувано | 18.10.04 15:02 |
|
Привет ...
mySQL 4.0.21
CREATE TABLE `sections` (
`id` int(11) unsigned NOT NULL auto_increment,
`title` varchar(100) NOT NULL default '',
`code` varchar(4) NOT NULL default '',
`descr` varchar(50) NOT NULL default '',
`content` text NOT NULL,
`last_edited` datetime NOT NULL default '0000-00-00 00:00:00',
`disabled` tinyint(1) unsigned NOT NULL default '0',
PRIMARY KEY (`id`)
) TYPE=MyISAM
mysql> select id from sections;
+----+
| id |
+----+
| 3 |
| 7 |
| 8 |
| 9 |
| 12 |
| 13 |
| 14 |
| 15 |
+----+
8 rows in set (0.00 sec)
Проблем:
Как с една заявка да изкарам съществуващите най-близка по-малка и най-близката по-голяма стойност от дадена:
Примерно за 14 трябва да получа 13 и 15, за 9 - 8 и 12 ... постигам нужния ми резултат с :
SELECT MAX(t1.id) AS my_min, MIN(t2.id) AS my_max
FROM sections AS t1 JOIN sections AS t2
WHERE t2.id > 8 AND t1.id < 8
но ако пусна заявката със стойност, която е извън границите на моето id, получавам два null-a :(
С други думи проблема ми е примерно за търсена стойност 3 да получа - 3 и 7, а за 15 - 14 и 15 ...
Тръгнах така, но не получавам, това което ми е нужно, пък и логиката ми нещо съвсем окуця ... :(
SELECT COALESCE(MAX(t1.id),MIN(t3.id)) AS my_min, COALESCE(MIN(t2.id),MAX(t3.id)) AS my_max
FROM sections AS t1
JOIN sections AS t2
JOIN sections AS t3
WHERE t2.id > 3 AND t1.id < 3
Предварително мерси ...
| |
Тема
|
Re: Ама откъде го измъкна това COALESCE???
[re: Cтyдeнт]
|
|
Автор |
salle (един такъв) |
Публикувано | 18.10.04 16:49 |
|
COALESCE() пък какво общо има в случая?
що не си направиш две отделни заявки с LIMIT 1 и да ги обединиш с UNION?
mysql> SELECT * FROM t;
+----+
| id |
+----+
| 3 |
| 7 |
| 8 |
| 9 |
| 12 |
| 13 |
| 14 |
| 15 |
+----+
8 rows in set (0.00 sec)
mysql> SET @val:=9; (SELECT MAX(id) FROM t WHERE id < @val) UNION (SELECT MIN(id) FROM t WHERE id > @val);
Query OK, 0 rows affected (0.02 sec)
+---------+
| MAX(id) |
+---------+
| 8 |
| 12 |
+---------+
2 rows in set (0.02 sec)
Наистина трябва да си поиграеш в граничните случаи ама не го прави с тая грозотия COALESCE, Използвай IF или направо IFNULL
А за да получиш 2 стойности и в случая когато таблицата има само един ред използвай UNION ALL
Редактирано от salle на 18.10.04 16:52.
| |
Тема
|
Трябват ми двете стоиности в един ред !
[re: salle]
|
|
Автор | Cтyдeнт (Нерегистриран) |
Публикувано | 18.10.04 17:14 |
|
Пролемът е, че ми трябват двете стойности в един ред ... с UNION ми е ясно, че мога да ги получа ... няма ли вариант за някакво обединение ?
| |
Тема
|
Re: А каква е разликата?
[re: Cтyдeнт]
|
|
Автор |
salle (един такъв) |
Публикувано | 19.10.04 11:23 |
|
Каква е разликата дали имаш
+-----+-----+
| min | max |
+-----+-----+
| 3 | 5 |
+-----+-----+
+---------+
| min_max |
+---------+
| 3 |
| 5 |
+---------+
| |
Тема
|
Голяма ...
[re: salle]
|
|
Автор | Cтyдeнт (Нерегистриран) |
Публикувано | 20.10.04 15:53 |
|
В единия вариант имаш достъп веднага ... няма нужда от итерации ... а в другия трябва да се цикли ...
| |
|
От MySQL не разбирам (дали поддържа субселекти), на Оракъл може нещо такова да се направи:
select
( select
Max(value)
from
MY_TABLE
where
(value < neshtoto_koeto_e_granicata_okolo_koiato_se_vyrtim)
) as LOWER_NEAREST_VALUE,
( select
Min(value)
from
MY_TABLE
where
(value > neshtoto_koeto_e_granicata_okolo_koiato_se_vyrtim)
) as UPPER_NEAREST_VALUE
from
DUAL
Ама си мисля, че и да имаш 1-2 реда повече код за да обработиш Result set от 2 записа е все тая.
Edit: Ако neshtoto_koeto_e_granicata_okolo_koiato_se_vyrtim е най-голямата и/или най-малката стойност в таблицата можеш да си облечеш субселектите с Nvl (еквивалента в МъСЯЛ (:-))) - Nvl( (select ..... from .....) , neshtoto_koeto_e_granicata_okolo_koiato_se_vyrtim)
Редактирано от timmyyy на 20.10.04 16:33.
| |
|
|
|
|