Comment procédez-vous LIMIT
dans DB2 pour iSeries?
J'ai une table avec plus de 50 000 enregistrements et je veux renvoyer des enregistrements de 0 à 10 000 et des enregistrements de 10 000 à 20 000.
Je sais qu'en SQL, vous écrivez LIMIT 0,10000
à la fin de la requête pour 0 à 10 000 et LIMIT 10000,10000
à la fin de la requête pour 10 000 à 20 000
Alors, comment cela se fait-il dans DB2? Quel est le code et la syntaxe? (Un exemple de requête complet est apprécié)
Développé cette méthode:
Vous avez besoin d'une table qui a une valeur unique qui peut être commandée.
Si vous voulez des rangées 10 000 à 25 000 et que votre table compte 40 000 rangées, vous devez d’abord obtenir le point de départ et le total des rangées:
int start = 40000 - 10000;
int total = 25000 - 10000;
Et puis passez ces par code à la requête:
SELECT * FROM
(SELECT * FROM schema.mytable
ORDER BY userId DESC fetch first {start} rows only ) AS mini
ORDER BY mini.userId ASC fetch first {total} rows only
Utiliser FETCH FIRST [n] ROWS ONLY
:
SELECT LASTNAME, FIRSTNAME, EMPNO, SALARY
FROM EMP
ORDER BY SALARY DESC
FETCH FIRST 20 ROWS ONLY;
Pour obtenir des plages, vous devez utiliser ROW_NUMBER()
(depuis la v5r4) et utiliser celui-ci dans la clause WHERE
: (volé à partir d'ici: http://www.justskins.com/forums/db2-select-how-to- 123209.html )
SELECT code, name, address
FROM (
SELECT row_number() OVER ( ORDER BY code ) AS rid, code, name, address
FROM contacts
WHERE name LIKE '%Bob%'
) AS t
WHERE t.rid BETWEEN 20 AND 25;
La prise en charge de OFFSET et LIMIT a récemment été ajoutée à DB2 pour i 7.1 et 7.2. Vous avez besoin des niveaux de groupe DB PTF suivants pour obtenir cette prise en charge:
Voir ici pour plus d'informations: OFFSET et LIMIT documentation , DB2 for i Enhancement Wiki
Voici la solution que j'ai trouvée:
select FIELD from TABLE where FIELD > LASTVAL order by FIELD fetch first N rows only;
En initialisant LASTVAL sur 0 (ou '' pour un champ de texte), puis en le définissant sur la dernière valeur du dernier ensemble d'enregistrements, la table sera divisée en morceaux de N.
La solution de @ elcool est une bonne idée, mais vous devez connaître le nombre total de lignes (qui peut même changer pendant l'exécution de la requête!). Je propose donc une version modifiée, qui nécessite malheureusement 3 sous-requêtes au lieu de 2:
select * from (
select * from (
select * from MYLIB.MYTABLE
order by MYID asc
fetch first {last} rows only
) I
order by MYID desc
fetch first {length} rows only
) II
order by MYID asc
où {last}
doit être remplacé par le numéro de ligne du dernier enregistrement dont j'ai besoin et {length}
doit être remplacé par le nombre de lignes dont j'ai besoin, calculé sous la forme last row - first row + 1
.
Par exemple. si je veux des lignes de 10 à 25 (au total 16 lignes), {last}
sera 25 et {length}
sera 25-10 + 1 = 16.
Vous devriez également envisager la clause OPTIMIZE FOR n ROWS. Plus de détails sur tout cela dans la documentation DB2 LUW dans le Instructions pour restreindre les instructions SELECT topic:
Essaye ça
SELECT * FROM
(
SELECT T.*, ROW_NUMBER() OVER() R FROM TABLE T
)
WHERE R BETWEEN 10000 AND 20000
Il existe 2 solutions pour paginer efficacement sur une table DB2:
1 - la technique utilisant la fonction row_number () et la clause OVER qui a été présentée sur un autre poste ("SELECT row_number () OVER (ORDER BY ...)"). Sur certaines grandes tables, j'ai parfois remarqué une dégradation des performances.
2 - la technique utilisant un curseur déroulant. L'implémentation dépend du langage utilisé. Cette technique semble plus robuste sur les grandes tables.
J'ai présenté les 2 techniques mises en œuvre dans PHP lors d'un séminaire l'année prochaine. La diapositive est disponible sur ce lien: http://gregphplab.com/serendipity/uploads/slides/DB2_PHP_Best_practices.pdf
Désolé mais ce document n'est qu'en français.
Theres ces options disponibles: -
DB2 has several strategies to cope with this problem.
You can use the "scrollable cursor" in feature.
In this case you can open a cursor and, instead of re-issuing a query you can FETCH forward and backward.
This works great if your application can hold state since it doesn't require DB2 to rerun the query every time.
You can use the ROW_NUMBER() OLAP function to number rows and then return the subset you want.
This is ANSI SQL
You can use the ROWNUM pseudo columns which does the same as ROW_NUMBER() but is suitable if you have Oracle skills.
You can use LIMIT and OFFSET if you are more leaning to a mySQL or PostgreSQL dialect.