Bonjour,
Est-il possible avec DB2 de limiter le nombre de résultats d'une requête, mais à partir d'un offset donné ? Par exemple, je voudrais, pour une requête retournant une centaine de lignes, les lignes 30 à 75.
Bonjour,
Est-il possible avec DB2 de limiter le nombre de résultats d'une requête, mais à partir d'un offset donné ? Par exemple, je voudrais, pour une requête retournant une centaine de lignes, les lignes 30 à 75.
Il n'y a pas comme en MySql un système de pagination mais tu peux résoudre le problème ainsi.
J'espère que cela résoud ton problème.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 WITH TEMPTABLE AS (SELECT *, ROW_NUMBER() OVER (ORDER BY monChampTri DESC) AS NUMREC FROM maTable) SELECT * FROM TEMPTABLE WHERE NUMREC BETWEEN 30 AND 75
Jab y'a pas plus imple que ça pour limiter le nombre de lignes retournées par un select?
Car j'ai une requête qui doit me ramener tellement de lignes que l'as400 monte a 90% d'utilisation donc tout le monde gueule à mon taf
J'ai essayer avec la clausemais ça ne sert pas à grand chose dans mon cas donc si il y avait une solution assez simple ce serait cool
Code : Sélectionner tout - Visualiser dans une fenêtre à part OPTIMIZE FOR 20 ROWS
merci d'avance
En effet optimize ne sert pas à limiter le résultat. Il y a bien la clause
mais comme cela l'indique, c'est les x premières lignes.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 FETCH FIRST n ROW ou ROWS (je ne sais plus)
Avec tu peux optimizer le premier SELECT mais in fine tu devras quand même tout lire.
Une option serait de créer une table temporaire avec le premier SELECT ce qui évite de le regénérer à chaque fois. Tu mets NumRec dans la clé primaire pour optimizer la seconde requête. Tu peux éventuellement ne mettre dans cette table temporaire que numrec et la clé primaire de ta table et travailler avec une jointure. La création de la table devrait être plus rapide.
Sinon je ne vois pas mais peut être que d'autres ?
J'essaye de me renseigner.
Et l'idée toute simple de réécrire la requête de façon à ne ramener qu'un nombre limité et raisonnable de lignes ?
Merci jab pour ta réponse mais le problème c'est que je ne veux pas que le select cherche tout les enregistrements!!
Merci Luc pour ta réponse qui va je pense faire avancer les choses , si ma requête mets aussi longtemps à s'éxécuter c'est qu'elle fait une liaison entre 3tables qui sont également liées sur elle-même donc je ne peut pas faire plus simple sinon je n'aurais pas le résultat que je veux. Je précise que mes tables comportent chacune environ 41000 enregistrements distinct donc je pense que le faire que la requête soit aussi longue vient de là
Peux-tu montrer la commande que tu utilise actuellement, il sera plus facile de se rendre compte de quoi faire.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 SELECT m9cono, m9itno FROM mitfac WHERE m9cono not in (SELECT PHPRNO FROM mpdhed, mitmas WHERE MPDHED.PHCONO=m9cono AND MITMAS.MMITNO=m9itno AND (MITMAS.MMMABU=2 AND (phcono NOT LIKE '7%' OR phcono like 8%))) AND m9cono=100
Les 2 mon capitaine. Mais il me semble qu'il faut ajouter ONLY à la finEnvoyé par jab
Yoyopi, si ta requête est longue c'est peut-être aussi parce qu'il y a création d'index temporaires.
Code : Sélectionner tout - Visualiser dans une fenêtre à part FETCH FIRST n ROW(S) ONLY
Salut gwellan tu vas bien depuis le temps?!!!
Oui ma requête créer des index, c'est pas possible d'éviter leur création?
Le FETCH ca va pas m'aider car je veux que mon select lorqu'il a trouver x enregistrements il s'arrète mais ça a pas l'air possible
Ca va, merci
Si tu as un index sur :Si dans ta requête tu fais :
Code : Sélectionner tout - Visualiser dans une fenêtre à part col1, col2, col3Il risque de ne pas prendre ton index. IBM recommande de mettre tes conditions dans le même ordre que pour l'index :
Code : Sélectionner tout - Visualiser dans une fenêtre à part where col2=x and col1=y and col3=zEt si tu fais :
Code : Sélectionner tout - Visualiser dans une fenêtre à part where col1=y and col2=x and col3=zC'est perdu d'avance...
Code : Sélectionner tout - Visualiser dans une fenêtre à part where col2=x and col3=y
Par contrefonctionnera parfaitement.
Code : Sélectionner tout - Visualiser dans une fenêtre à part where col1=x and col2=y
Après sur les requêtes complexes il lui arrive quand même de se perdre. Ca m'est arrivé plus d'une fois où l'optimiseur m'a dit "ce serait bien de créer un index sur les colonnes x, y", tu crées l'index en question et il te redit quand même que "ce serait bien de créer un index sur x, y".
Note :
Je parle là de DB2/400, utilisé par Yoyopi. Je ne sais pas si ce fonctionnement est indentique sur les autres plateformes DB2.
Sur Iseries V5r3 sous Db2400 ,
Il est possible d'utiliser un curseur dit scrollable qui permet de se position a l'enregistrement de son choix avec l'instruction FETCH relative et aussi de lire le nombre d'enregistrement de son choix.
Voici un exemple tiré du redbook d'IBM sur les procédures stockées :
Stored Procedures
and Triggers
on DB2 Universal Database for iSeries
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149 CREATE PROCEDURE GETRANK 1 (IN proc_year DECIMAL(4,0),1 IN proc_month DECIMAL(2,0),1 INOUT proc_rank INTEGER)1 RESULT SETS 2 2 LANGUAGE SQL 3 BEGIN DECLARE highsales DECIMAL(11,2); DECLARE lowsales DECIMAL(11,2); DECLARE rank1 INTEGER; DECLARE rank2 INTEGER; DECLARE SQLStmt CHAR(512); DECLARE c1 DYNAMIC SCROLL CURSOR WITH RETURN FOR s1;4 DECLARE c2 DYNAMIC SCROLL CURSOR WITH RETURN FOR s2;4 ---Check if it is Null for Month IF proc_month IS NULL or proc_month =0 THEN --Get Highest Rank Suppliers SET SQLStmt='SELECT yearsales FROM yearsale WHERE year=? ORDER BY yearsales DESC';5 PREPARE s1 FROM SQLStmt; OPEN c1 USING proc_year; FETCH RELATIVE proc_rank FROM c1 INTO highsales; IF highsales IS NULL THEN FETCH LAST FROM c1 INTO highsales; END IF; CLOSE c1; SET SQLStmt='SELECT count(*)FROM yearsale WHERE year=?AND yearsales>=?'; PREPARE s1 FROM SQLStmt; OPEN c1 USING proc_year,highsales; FETCH c1 INTO rank1; CLOSE c1; SET SQLStmt='SELECT supplier_name,yearsales FROM yearsale WHERE year=? AND yearsales>=?ORDER BY yearsales DESC';5 PREPARE s1 FROM SQLStmt; OPEN c1 USING proc_year,highsales; --Get Lowest Rank Suppliers SET SQLStmt='SELECT yearsales FROM yearsale WHERE year=? ORDER by yearsales ASC'; PREPARE s2 FROM SQLStmt; OPEN c2 USING proc_year; FETCH RELATIVE proc_rank FROM c2 INTO lowsales;6 IF lowsales IS NULL THEN 7 FETCH LAST FROM c2 INTO lowsales; END IF; CLOSE c2; SET SQLStmt='SELECT count(*)FROM yearsale WHERE year=?AND yearsales<=?'; PREPARE s2 FROM SQLStmt; OPEN c2 USING proc_year,lowsales; FETCH c2 INTO rank2; CLOSE c2; SET SQLStmt='SELECT supplier_name,yearsales FROM yearsale WHERE year=? AND yearsales<=?ORDER BY yearsales ASC'; PREPARE s2 FROM SQLStmt; OPEN c2 USING proc_year,lowsales; ELSE --Get Highest Rank Suppliers SET SQLStmt='SELECT totalsales FROM TOTALSALE WHERE year=? AND month=?ORDER BY totalsales DESC'; PREPARE s1 FROM SQLStmt; OPEN c1 USING proc_year,proc_month; FETCH RELATIVE proc_rank FROM c1 INTO highsales; IF highsales IS NULL THEN FETCH LAST FROM c1 INTO highsales; END IF; CLOSE c1; SET SQLStmt='SELECT count(*)FROM totalsale WHERE year=?AND month=? AND totalsales>=?'; PREPARE s1 FROM SQLStmt; OPEN c1 USING proc_year,proc_month,highsales; FETCH c1 INTO rank1; CLOSE c1; SET SQLStmt='SELECT supplier_name,totalsales FROM totalsale WHERE year=? AND month=?AND totalsales>=? ORDER BY totalsales DESC'; PREPARE s1 FROM SQLStmt; OPEN c1 USING proc_year,proc_month,highsales; --Get Lowest Rank Suppliers SET SQLStmt='SELECT totalsales FROM totalsale WHERE year=?AND month=? ORDER by totalsales ASC'; PREPARE s2 FROM SQLStmt; OPEN c2 USING proc_year,proc_month; FETCH RELATIVE proc_rank FROM c2 INTO lowsales; IF lowsales IS NULL THEN FETCH LAST FROM c2 INTO lowsales; END IF; CLOSE c2; SET SQLStmt='SELECT count(*)FROM totalsale WHERE year=?AND month=? AND totalsales<=?'; PREPARE s2 FROM SQLStmt; OPEN c2 USING proc_year,proc_month,lowsales; FETCH c2 INTO rank2; CLOSE c2; SET SQLStmt='SELECT supplier_name,totalsales FROM totalsale WHERE year=? AND month=?AND totalsales<=? ORDER BY totalsales ASC'; PREPARE s2 FROM SQLStmt; OPEN c2 USING proc_year,proc_month,lowsales; END IF; IF rank1<rank2 THEN SET proc_rank=rank2; ELSE SET proc_rank=rank1; END IF; END
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager