Autor Zpráva
stepanka
Profil *
Ahoj,

neřešil jste někdy někdo problém s výběrem řádků okolo jednoho konkrétníko řádku? To znamená výběr vždy 9 řádků, kde určitý řádek je uprostřed a 4 před ním a 4 za ním? I s ošetřením, že určitý záznam je první, druhý, předposlední, poslední, atd., v tom případě vybrat zase 9 záznamů, ale natáhnout ty předchozí, nebo následující.

Stačí mi kostra, pak si to doladím. Už jsem prošla celý google, ale žádné řešení mi nesedělo.

Moc děkuju!
Kajman
Profil
Můžete si spočítat na kolikátém místě je hledaný řádek - zjistíte, že např. na 42. a podle toho stanovíte offset
limit 9 offset 37
Hned víte, že první řádek bude mít číslo 38 (pozor na situace, kdy by vyšel záporný offset, to si ošetřete).

Při velkém offsetu bych tipnul, že už může být rychlejší něco na způsob z faq s limitem 4 (5 při rovnosti id) - tedy dva dotazy na 4 před a 4 za konkrétním řádkem spojené unionem.
stepanka
Profil *
Kajman:
Moc děkuju za reakci.

V PHP bych to nějak vymyslela, ale určitě to musí jít i na úrovni databáze, ne?
Zatím mi nejvíce sedí:

SELECT * 
FROM tabulka
WHERE id > ID_HLEDANEHO RADKU - 5
OR (id+3) > (SELECT COUNT(1) FROM tabulka)
LIMIT 9

Selhává to akorát na konci tabulky, kde místo, aby natahoval data dopředu, tak je začne ořezávat a místo 9ti jich zobrazí jen 8, 7, 6, atd. Na začátku tabulky to funguje perfektně. Neuměl byste to nějak upravit?

Děkuju.
panther
Profil
stepanka:
napada me, co budes delat, az nektere ID (predpokladam auto increment) smazes? Pak ti to bude vybirat mene zaznamu.
Kajman
Profil
No, na úrovni db to asi půjde, jen si nejsem jistý, jestli to je nejpřehlednější, ale svižné by to mohlo být

SELECT id
FROM   ((SELECT id,
                @vzdalenost := @vzdalenost + 1 vzdalenost
         FROM   tabulka,
                (SELECT @vzdalenost := 0) v
         WHERE  id < id_hledaneho_radku
         ORDER  BY id DESC
         LIMIT  8)
        UNION ALL
        (SELECT id,
                @vzdalenost := 0 vzdalenost
         FROM   tabulka
         WHERE  id = id_hledaneho_radku)
        UNION ALL
        (SELECT id,
                @vzdalenost := @vzdalenost + 1 vzdalenost
         FROM   tabulka
         WHERE  id > id_hledaneho_radku
         ORDER  BY id
         LIMIT  8)
        ORDER  BY vzdalenost,
                  id
        LIMIT
        9) t
ORDER  BY id 
stepanka
Profil *
panther:
Smazání nevadilo, ale stejně to nebylo dotažené, takže to asi nepoužiju. Ale díky za odpověď.

Kajman:
Tohle právě ořezává data. Když vybírám okolo záznamu, který je na začátku, tak se druhá půlka výběru nenatáhne. A stejně tak, když vybírám okolo řádku na konci tabulky, tak se nenatáhne výběr na začátku. Jako že těch vybraných řádků je pak různý počet. Tak asi bude nejlepší to PHP..
Kajman
Profil
stepanka:
Jako že těch vybraných řádků je pak různý počet

Pokud je v tabulce alespoň 9 záznamů, vrátí to při jakémkoliv exitstujícím hledaném id 9 záznamů.
stepanka
Profil *
Kajman:
Opravdu? Já nevím, dotaz jsem pouze zkopírovala a 3x nahradila řetězec "id_hledaneho_radku". Když to spustím s ID někde uprostřed:
Zobrazeny záznamy 0 - 17 (18 celkem, dotaz trval 0.0006 sekund)

ID druhé ze začátku:
Zobrazeny záznamy 0 - 10 (11 celkem, dotaz trval 0.0007 sekund)

ID druhé od konce:
Zobrazeny záznamy 0 - 10 (11 celkem, dotaz trval 0.0005 sekund)
Kajman
Profil
To je divné, limit 9 na řádku 23 a 24 by neměl vrátit více záznamů.
stepanka
Profil *
Kajman:
Zkusím si s tím ještě pohrát, zatím mi to stále vytahuje stejné počty záznamů. Každopádně moc děkuju.
Kajman
Profil
Třeba se to na jiných verzích chová jinak, než jsem zvyklý. Každopádně po zazávorkování by to už bylo tuze divné, kdyby to vrátilo záznamů více...


SELECT *
FROM   (SELECT *
        FROM   ((SELECT tabulka.*,
                        @vzdalenost := @vzdalenost - 1 vzdalenost
                 FROM   tabulka,
                        (SELECT @vzdalenost := 0) v
                 WHERE  id < id_hledaneho_radku
                 ORDER  BY id DESC
                 LIMIT  8)
                UNION ALL
                (SELECT tabulka.*,
                        @vzdalenost := 0 vzdalenost
                 FROM   tabulka
                 WHERE  id = id_hledaneho_radku)
                UNION ALL
                (SELECT tabulka.*,
                        @vzdalenost := @vzdalenost + 1 vzdalenost
                 FROM   tabulka
                 WHERE  id > id_hledaneho_radku
                 ORDER  BY id
                 LIMIT  8)) x
        ORDER  BY Abs(vzdalenost),
                  id
        LIMIT  9) t
ORDER  BY id
stepanka
Profil *
Kajman:
Úžasné! Teď už mi to vypisuje stále 9 řádků. Asi tedy jiná verze... Mockrát děkuju.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: