соседние поля в SELECT

asidlink

Новичок
соседние поля в SELECT

как добиться от
SELECT * FROM `table` WHERE `money`=(SELECT `money` FROM `table` ORDER BY `id` LIMIT 1)
чтобы выдавать только те строки, которые идут друг за другом если у них равны `money`
 

Mr_Max

Первый класс. Зимние каникулы ^_^
Команда форума
Попробуй более подробно объяснить вопрос.
 

asidlink

Новичок
например, в бд есть 10 записей, в первой, второй, третей и в пятой значения поля `money` равны. мой запрос выдаст 1,2,3,5 запись. но мне нужно, чтобы он выдал только те записи, которые соседние, т.е. 1,2 и 3.
 

Fortop

Новичок
10 записей, в первой, второй, третей и в пятой значения поля `money` равны. мой запрос выдаст 1,2,3,5 запись.
Круто, а что должен запрос выдать если в базе есть 1,2,3,5,6,7 записи с равным полем `money`?
 

zerkms

TDD infected
Команда форума
asidlink
озвучь исходную задачу, которую ты решаешь с помощью такого изврата.
 

Fortop

Новичок
asidlink
тогда должен выдать только 1,2,3
А почему не 5,6,7?

Наколеночное решение.
Код:
[color="#0000ff"]use[/color] test;
[color="#008000"]-- create[/color]
[color="#0000ff"]CREATE[/color] [color="#0000ff"]TABLE[/color] `strange` (
 `id` [color="#0000ff"]int[/color](11) [color="#0000ff"]NOT[/color] [color="#0000ff"]NULL[/color] AUTO_INCREMENT,
 `money` [color="#0000ff"]int[/color](11) [color="#0000ff"]NOT[/color] [color="#0000ff"]NULL[/color],
 [color="#0000ff"]PRIMARY[/color] [color="#0000ff"]KEY[/color] (`id`)
) ENGINE=InnoDB

[color="#008000"]-- insert[/color]
[color="#0000ff"]insert[/color] [color="#0000ff"]into[/color] strange (money) [color="#0000ff"]values[/color] (1),(1),(1),(2),(2),(1),(1),(1),(1),(2),(3),(2),(2),(2),(3),(3),(3);

[color="#008000"]-- procedure[/color]
DELIMITER //
[color="#0000ff"]CREATE[/color] [color="#0000ff"]PROCEDURE[/color] getSequence ([color="#0000ff"]IN[/color] mn [color="#0000ff"]INT[/color]) 
[color="#0000ff"]BEGIN[/color]
[color="#0000ff"]SELECT[/color] `id` [color="#0000ff"]FROM[/color] strange [color="#0000ff"]as[/color] R
[color="#0000ff"]JOIN[/color] 
  ([color="#0000ff"]SELECT[/color] 
    ([color="#0000ff"]SELECT[/color] [color="#0000ff"]MIN[/color](CID)
      [color="#0000ff"]FROM[/color] (
        [color="#0000ff"]select[/color] `id` [color="#0000ff"]AS[/color] CID, 
          [color="#0000ff"]CASE[/color] 
            [color="#0000ff"]WHEN[/color] [color="#0000ff"]EXISTS[/color] ([color="#0000ff"]SELECT[/color] `id` [color="#0000ff"]FROM[/color] strange [color="#0000ff"]as[/color] SS1 [color="#0000ff"]WHERE[/color] `id` = CID -1 [color="#0000ff"]AND[/color] money = mn) 
            [color="#0000ff"]THEN[/color] 1 
            [color="#0000ff"]ELSE[/color] 0 
          [color="#0000ff"]END[/color] [color="#0000ff"]AS[/color] P, 
          [color="#0000ff"]CASE[/color] 
            [color="#0000ff"]WHEN[/color] [color="#0000ff"]EXISTS[/color] ([color="#0000ff"]SELECT[/color] `id` [color="#0000ff"]FROM[/color] strange [color="#0000ff"]as[/color] SS2 [color="#0000ff"]WHERE[/color] `id`= CID +1 [color="#0000ff"]AND[/color] money = mn) 
            [color="#0000ff"]THEN[/color] 1 
            [color="#0000ff"]ELSE[/color] 0 
            [color="#0000ff"]END[/color] [color="#0000ff"]AS[/color] N 
        [color="#0000ff"]FROM[/color] strange [color="#0000ff"]as[/color] SS3
        [color="#0000ff"]WHERE[/color] money = mn
      ) [color="#0000ff"]as[/color] seqMx
      [color="#0000ff"]WHERE[/color] seqMx.N = 0 [color="#0000ff"]AND[/color] seqMx.P <> 0) [color="#0000ff"]AS[/color] MXCID,
    ([color="#0000ff"]SELECT[/color] [color="#0000ff"]MAX[/color](CID)
      [color="#0000ff"]FROM[/color] (
        [color="#0000ff"]select[/color] `id` [color="#0000ff"]AS[/color] CID, 
          [color="#0000ff"]CASE[/color] 
            [color="#0000ff"]WHEN[/color] [color="#0000ff"]EXISTS[/color] ([color="#0000ff"]SELECT[/color] `id` [color="#0000ff"]FROM[/color] strange [color="#0000ff"]as[/color] SS4 [color="#0000ff"]WHERE[/color] `id` = CID -1 [color="#0000ff"]AND[/color] money = mn) 
            [color="#0000ff"]THEN[/color] 1 
            [color="#0000ff"]ELSE[/color] 0 
          [color="#0000ff"]END[/color] [color="#0000ff"]AS[/color] P, 
          [color="#0000ff"]CASE[/color] 
            [color="#0000ff"]WHEN[/color] [color="#0000ff"]EXISTS[/color] ([color="#0000ff"]SELECT[/color] `id` [color="#0000ff"]FROM[/color] strange [color="#0000ff"]as[/color] SS5 [color="#0000ff"]WHERE[/color] `id`= CID +1 [color="#0000ff"]AND[/color] money = mn) 
            [color="#0000ff"]THEN[/color] 1 
            [color="#0000ff"]ELSE[/color] 0 
            [color="#0000ff"]END[/color] [color="#0000ff"]AS[/color] N 
        [color="#0000ff"]FROM[/color] strange [color="#0000ff"]as[/color] SS6
        [color="#0000ff"]WHERE[/color] money = mn
      ) [color="#0000ff"]as[/color] seqMn
      [color="#0000ff"]WHERE[/color] seqMn.P = 0 [color="#0000ff"]AND[/color] seqMn.N <> 0 [color="#0000ff"]AND[/color] seqMn.CID < MXCID) [color="#0000ff"]AS[/color] MNCID
  ) [color="#0000ff"]AS[/color] T
[color="#0000ff"]ON[/color] T.MXCID >= R.`id` [color="#0000ff"]AND[/color] T.MNCID <= R.`id`;
[color="#0000ff"]END[/color] //
DELIMITER ;

[color="#008000"]-- sample usage[/color]
[color="#0000ff"]CALL[/color] getSequence(3);
EXPLAIN жестокий и использовать на таблицах более нескольких тысяч записей я бы не рекомендовал
Код:
+----+--------------------+------------+--------+---------------+---------+---------+------+------+--------------------------+
| id | select_type        | table      | type   | possible_keys | key     | key_len | ref  | rows | Extra                    |
+----+--------------------+------------+--------+---------------+---------+---------+------+------+--------------------------+
|  1 | PRIMARY            | <derived2> | system | NULL          | NULL    | NULL    | NULL |    1 |                          |
|  1 | PRIMARY            | R          | index  | PRIMARY       | PRIMARY | 4       | NULL |   17 | Using where; Using index |
|  2 | DERIVED            | NULL       | NULL   | NULL          | NULL    | NULL    | NULL | NULL | No tables used           |
|  7 | DEPENDENT SUBQUERY | <derived8> | ALL    | NULL          | NULL    | NULL    | NULL |    4 | Using where              |
|  8 | DERIVED            | SS6        | ALL    | NULL          | NULL    | NULL    | NULL |   17 | Using where              |
| 10 | DEPENDENT SUBQUERY | SS5        | eq_ref | PRIMARY       | PRIMARY | 4       | func |    1 | Using where              |
|  9 | DEPENDENT SUBQUERY | SS4        | eq_ref | PRIMARY       | PRIMARY | 4       | func |    1 | Using where              |
|  3 | SUBQUERY           | <derived4> | ALL    | NULL          | NULL    | NULL    | NULL |    4 | Using where              |
|  4 | DERIVED            | SS3        | ALL    | NULL          | NULL    | NULL    | NULL |   17 | Using where              |
|  6 | DEPENDENT SUBQUERY | SS2        | eq_ref | PRIMARY       | PRIMARY | 4       | func |    1 | Using where              |
|  5 | DEPENDENT SUBQUERY | SS1        | eq_ref | PRIMARY       | PRIMARY | 4       | func |    1 | Using where              |
+----+--------------------+------------+--------+---------------+---------+---------+------+------+--------------------------+
Но можно подтюнинговать как минимум индексы.

Есть нюанс, если ID идут не по-порядку, а имеются "дырки" - то работать не будет.
Для поиска дырок можно использовать другой скрипт :D :D
А можно усложнить и этот для получения и использования порядкового номера записи.

Вы еще хотите добиваться этого? Или, быть может, лучше подумать?
 

asidlink

Новичок
Автор оригинала: zerkms
asidlink
озвучь исходную задачу, которую ты решаешь с помощью такого изврата.
Нужно в курсовой по экономике сжать данные за день по котировкам акций одной компании.

id | date | time | vollume | money_last | money_max |
201003251700 | 25.03.2010 | 17:01 | 1050 | 659.45 | 659.50 |
201003251702 | 25.03.2010 | 17:02 | 996 | 659.40 | 659.50 |
201003251706 | 25.03.2010 | 17:06 | 1750 | 659.43 | 659.50 |
201003251708 | 25.03.2010 | 17:08 | 950 | 659.44 | 659.50 |
201003251709 | 25.03.2010 | 17:09 | 951 | 659.41 | 659.55 |
201003251711 | 25.03.2010 | 17:11 | 952 | 659.43 | 659.55 |
201003251715 | 25.03.2010 | 17:15 | 950 | 659.44 | 659.50 |
201003251720 | 25.03.2010 | 17:20 | 950 | 659.44 | 659.50 |

записей несколько тысяч, поскольку котировки (money_last) меняются почти ежесекундно. Поле `money_max` меняется реже (~1 раз в 10сек.)
Надо одним запросом выдать все строки, в которых `money_max` равно `money_max`первой строке (т.е. с самым маленьким id) но при условии, что все эти строки будут соседними.т.е.:

id | date | time | vollume | money_last | money_max |
201003251700 | 25.03.2010 | 17:01 | 1050 | 659.45 | 659.50 |
201003251702 | 25.03.2010 | 17:02 | 996 | 659.40 | 659.50 |
201003251706 | 25.03.2010 | 17:06 | 1750 | 659.43 | 659.50 |
201003251708 | 25.03.2010 | 17:08 | 950 | 659.44 | 659.50 |

Затем я усредню поля `vollume` и `money_last`
 

Fortop

Новичок
Надо одним запросом выдать все строки, в которых `money_max` равно `money_max`первой строке (т.е. с самым маленьким id) но при условии, что все эти строки будут соседними.т.е.:
Логики не вижу, в чем сжатие?

-~{}~ 25.03.10 16:36:

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

asidlink

Новичок
Fortop,
из полученных строк сформируется одна с усредненными значениями цен акций и объем торгов.
Затем следующие строки и т.д.
 

zerkms

TDD infected
Команда форума
вообще - существует куча методов сглаживания. и если мне память не изменяет, то статистика их изучает.
почему бы не покопать в сторону науки, отказавшись от изобретения колеса?
 
Сверху