2009-09-07 5 views
1

J'essaie de trouver une requête de sélection un peu inhabituelle. Tout d'abord, ce que j'ai est un identifiant d'une seule ligne dans la table. Je veux sélectionner un nombre de lignes de la table (disons le 10) avec la seule ligne avec l'identifiant que je sais être dans la table étant au milieu de l'ensemble de lignes. Donc il va sélectionner disons 4 lignes avant l'identifiant que je connais et 5 lignes après l'identifiant (ou 5, 4). Si l'ID est au début de la table ou à la fin si la table sélectionne toujours 10 lignes, par exemple si l'ID est la deuxième ligne de la table, il sélectionnera 1 ligne avant et 8 lignes. des rangs après. Lorsque l'identifiant est la dernière ligne, il sélectionne 9 lignes avant (plus celle avec l'identifiant, bien sûr). Je ne suis pas sûr d'être assez clair mais j'ai de la difficulté à expliquer cela d'une meilleure façon.SELECT aide à la requête SQL

EDIT:

Voici plus d'informations. Table Imaginez comme ceci (simplifié):

id title 
1  Title 1 
2  Title 2 
3  Title 3 
4  Title 4 
5  Title 5 
6  Title 6 
7  Title 7 
8  Title 8 
9  Title 9 
10 Title 10 
11 Title 11 
12 Title 12 
13 Title 13 
14 Title 14 
15 Title 15 
16 Title 16 
17 Title 17 
18 Title 18 
19 Title 19 
20 Title 20 
21 Title 21 
22 Title 22 
23 Title 23 
24 Title 24 
25 Title 25 

Maintenant, disons que l'identifiant que j'ai est 11, la requête sélectionnera ces lignes:

7, 8, 9, 10, **11**, 12, 13, 14, 15, 16 

Disons que l'ID est 2, la requête sélectionnez:

1, **2**, 3, 4, 5, 6, 7, 8, 9, 10 

Disons que l'ID est 25, la requête sélectionnera:

16, 17, 18, 19, 20, 21, 22, 23, 24, **25** 

Et ainsi de suite. J'espère que c'est plus clair maintenant.

+0

Pouvez-vous fournir les colonnes de la table? Comment déterminez-vous être au milieu de l'ensemble de lignes? –

+0

Eh bien, il est déterminé en fonction de l'ID je sais qui devrait être la rangée du milieu. J'ai ajouté plus d'informations dans mon message. –

Répondre

2
declare @p_id numeric, @p_range numeric 
select @p_id = 4 -- known ID 
, @p_range = 10 --range 
select * from myTable 
where id between (@p_id - (@p_range/2)) and (@p_id + (@p_range/2)) 
order by id 

Cela sélectionnera 10 enregistrements autour d'un ID connu (4), 5 avant, 5 après.

Vous aurez à faire un peu plus la manipulation si vous voulez avoir exactement 10 dossiers, et de travailler combien existent avant et après (dans le cas d'id = 2, etc.)

1

Je ne suis pas un gars MySQL, mais peut-être cela fonctionnera si les ID sont séquentiels et ininterrompue:

select ID, your_other_columns from (
    select 
    :yourID-ID+0.5 as priority, 
    * from T where ID between :yourID-9 and :yourID 
    union all 
    select 
    ID-:yourID as priority, 
    * from T where ID between :yourID and :yourID+9 
    where ID >= :yourID and :yourID >= ID-9 
) as T20 order by priority limit 10; 
+0

Ils ne doivent pas être séquentiels. Ils sont le plus souvent mais de temps en temps il y a un saut de plus de + 1 car le site utilise des transactions et ils échouent parfois. –

+0

Si MySQL prend en charge ROW_NUMBER(), il ne sera pas trop difficile avec des espaces dans les ID. Sans ROW_NUMBER, je ne peux pas penser à une solution efficace qui n'utilise pas un curseur ou une table temporaire numérotée. –

1

requête simple ... un peu laid)

SET @target := 11 
(SELECT * 
     FROM (
       (SELECT * FROM your_table WHERE id <= @target ORDER BY id desc LIMIT 10) 
         UNION 
       (SELECT * FROM your_table WHERE id > @target ORDER BY id asc LIMIT 9) 
     ) AS u ORDER BY ABS(CAST(u.id AS signed integer) - @target) ASC LIMIT 10 
) ORDER BY id;