[mysql] wyszukiwanie podszeregow liczb

0

Witam,
mam problem z napisaniem zapytania,
zalozmy, ze mam tablice tab

lp	war
1	3
2	4
3	5
4	6
5	9
6	11
7	12
8	13

teraz chcialbym w jakis sprytny sposob uzyskac select z outputem odpowiadajacym:

war
3
4
5
6
9
11
12
13
(elementy, ktore powinny zostac pominiete napisalem kolorem transparent)
otoz o co mi chodzi?
chcialbym, aby wybralo mi tylko te wartosci, ktore maja swojego nastepce i poprzednika,
wybralo 4 i 5, dlatego, ze poprzednikiem 4 jest 3, a nastepca 5 jest 6.
9 natomiast zostala usunieta, poniewaz nie ma nastepcy, ani nawet poprzednika

probowalem cos w tym stylu:

select war as zmienna from `tab` having 
count(select war from `tab` where war=zmienna-1)>0 
and
count(select war from `tab` where war=zmienna+1)>0 

jesli ktos zechcialby mi pomoc, to zamieszczam przykladowe dane

CREATE TABLE IF NOT EXISTS `tab` (
  `lp` int(11) NOT NULL auto_increment,
  `war` int(11) NOT NULL,
  PRIMARY KEY  (`lp`)
)
insert into tab (`war`) values (3),(4),(5),(8),(9),(11),(12),(13)
0
SELECT 
  a.war
FROM 
  tab a
where
  (SELECT count(*) FROM tab b WHERE a.war = b.war - 1) > 0
  AND (SELECT count(*) FROM tab b WHERE a.war = b.war + 1) > 0
0

dzieki wielkie,

mam jeszcze jeden problem i siedze dzisiaj caly dzien nad tym, otoz

create table tabela (`val` int(10) not null, `cont` int(10) not null,    PRIMARY KEY  (`val`,`cont`)); 
insert into tabela values  
(0,1), (1,1), (2,1), (4,1), (5,1), (6,2), 
(7,1), (8,1), (10,1), (11,1), (12,1), (13,1), 
(16,1), (17,1), (18,1), 

(0,2), (1,2), (2,2), (4,2), (5,2), (6,2), 
(7,2), (8,2), (10,2), (11,2), (12,2), (13,2), 
(16,2), (17,2);

chciałbym teraz, aby zapytanie wybralo
pierwszy podciag, ktorego val beda kolejnymi liczbami calkowitymi oraz bedzie zlozony z co najmniej 3 nastepujacych po sobie val, z tym, ze jesli ostatnim wyrazem ciagu jest ostatni element nie moze byc max(val);

moze przyklad:
taki mysql pseudokod:

select val from tabela
WHERE val>pierwszy wyraz, ktory nie ma poprzednika, ale ma 3 nastepcow
and
val>pierwszy wyraz, ktory ma 3 poprzednikow, ale nie ma nastepcy
and
pierwszy wyraz, ktory ma 3 poprzednikow, ale nie ma nastepcy!=max(val)

poprzednikiem rekordu A nazywam rekord B, taki, ze B.val+1=A.val,

chcialbym, aby ten select jako wynik zwracal pogrubiona czesc:

(0,1), (1,1), (2,1), (4,1), (5,1), (6,2),
(7,1), (8,1), (10,1), (11,1), (12,1), (13,1),
(16,1), (17,1), (18,1)

oraz
dla przykladu

(0,1), (1,1),
(16,1), (17,1), (18,1)
wynikiem powinien byc zbior pusty, bo ostatni wyraz podciagu majacego co najmniej 3 wyrazy jest zarazem najwieksza wartoscia val w tablicy

<font size="3">caly sens posta jest przekazany do tej linijki, nizej tresc moze byc bardzo ciezka w zrozumieniu</span>
z mojego kombinowania: (tutaj napisze to, co zrobilem samemu, jest to dosyc pogmatwane, bo wiele razy musialem gubic watek myslowy po to, aby rozwiazac jakis czesciowy, maly techniczny problem
probowalem zrobic to w ten sposob:

  1. tworze tabele tymczasowa, do ktorej wrzucam skrajne val opisujace szeregi, tj.
	CREATE TABLE if not exists `tmpzz` (
	  val int(11) NOT NULL,
	  `cont` int(11) NOT NULL,
	  PRIMARY KEY  (val,cont)
	) ENGINE=InnoDB DEFAULT CHARSET=latin1;	truncate table tmpzz;

    insert ignore into `tmpzz` 
	select val,cont from tabela a where cont=1 and
	( 
	(select count(val) from tabela b where b.val=a.val-1)=0
	and
	 (select count(val) from tabela b where b.val=a.val+1)>0
	and
	 (select count(val) from tabela b where b.val=a.val+2)>0
	and
	 (select count(val) from tabela b where b.val=a.val+3)>0
	 );

    insert ignore into `tmpzz` 
	select val,cont from tabela a where cont=1 and
	(
		(val != (select max(val) from tabela)) 
	and
		(select count(val) from tabela b where b.val=a.val+1)=0
	and
		(select count(val) from tabela b where b.val=a.val-1)>0
	and
		(select count(val) from tabela b where b.val=a.val-2)>0
	and
		(select count(val) from tabela b where b.val=a.val-3)>0
	); 

co powoduje, ze mam cos takiego:

+-----+------+
| val | cont |
+-----+------+
| 1 | 1 |
| 4 | 1 |
| 10 | 1 |
| 13 | 1 |
+-----+------+
8 rows in set (0.00 sec)
,
a teraz nie wiem jak z tego wyznaczyc przedzial od 1 do 4 z tabela.var

2. probowalem robic 2 tabele tymczasowa, do ktorej wkladam

select * from tmpzz where val!=(select max(val) from tmpzz) limit 2;

z tym, ze mam tutaj straszy problem z tym warunkiem, ze koniec "przedzialu" musi byc rozny od max(val),
3. chcialem zrobic 3 tabele, w ktorej byloby cos w stylu select val from tabela where val>(select min(val) from tmp2) and val>(select min(max) from tmp2),

ale nie przeszedlem nawet drugiego kroku,

EDIT:
chyba mi sie udalo, ale jednak problem nadal aktualny, bo optymalnosc mojego rozwiazania zostawia wiele do zyczenia

SELECT val
FROM tabela
WHERE val > (

SELECT min( val )
FROM tabela a
WHERE (
(

SELECT count( val )
FROM tabela b
WHERE b.val = a.val -1
) =0
AND (

SELECT count( val )
FROM tabela b
WHERE b.val = a.val +1
) >0
AND (

SELECT count( val )
FROM tabela b
WHERE b.val = a.val +2
) >0
AND (

SELECT count( val )
FROM tabela b
WHERE b.val = a.val +3
) >0
)
)
AND val < (

SELECT min( val )
FROM tabela a
WHERE (
(

SELECT count( val )
FROM tabela b
WHERE b.val = a.val +1
) =0
AND (

SELECT count( val )
FROM tabela b
WHERE b.val = a.val -1
) >0
AND (

SELECT count( val )
FROM tabela b
WHERE b.val = a.val -2
) >0
AND (

SELECT count( val )
FROM tabela b
WHERE b.val = a.val -3
) >0
)
)

1 użytkowników online, w tym zalogowanych: 0, gości: 1