Lorsque j'ai travaillé sur le Zend Framework's database component, nous avons essayé de résumer la fonctionnalité de la clause LIMIT
supportée par MySQL, PostgreSQL et SQLite. Cela est, la création d'une requête pourrait se faire de cette façon:Emulation de la clause MySQL LIMIT dans Microsoft SQL Server 2000
$select = $db->select();
$select->from('mytable');
$select->order('somecolumn');
$select->limit(10, 20);
Lorsque la base de données prend en charge LIMIT
, cela produit une requête SQL comme suit:
SELECT * FROM mytable ORDER BY somecolumn LIMIT 10, 20
Cela a été plus complexe pour les marques de base de données ne supporte pas LIMIT
(cette clause ne fait pas partie du langage SQL standard, d'ailleurs). Si vous pouvez générer des numéros de ligne, rendez l'ensemble de la requête une table dérivée et dans la requête externe, utilisez BETWEEN
. C'était la solution pour Oracle et IBM DB2. Microsoft SQL Server 2005 dispose d'une fonction ligne numéro similaire, on peut donc écrire la requête de cette façon:
SELECT z2.*
FROM (
SELECT ROW_NUMBER OVER(ORDER BY id) AS zend_db_rownum, z1.*
FROM (...original SQL query...) z1
) z2
WHERE z2.zend_db_rownum BETWEEN @offset+1 AND @[email protected];
Cependant, Microsoft SQL Server 2000 ne dispose pas de la fonction ROW_NUMBER()
. Donc, ma question est, pouvez-vous trouver un moyen d'émuler la fonctionnalité LIMIT
dans Microsoft SQL Server 2000, en utilisant uniquement SQL? Sans utiliser de curseurs ou T-SQL ou une procédure stockée. Il doit prendre en charge les deux arguments pour LIMIT
, à la fois compte et décalage. Les solutions utilisant une table temporaire ne sont pas non plus acceptables.
Edit:
La solution la plus courante pour MS SQL Server 2000 semble être comme celui ci-dessous, par exemple pour obtenir des lignes 50 à 75:
SELECT TOP 25 *
FROM (
SELECT TOP 75 *
FROM table
ORDER BY BY field ASC
) a
ORDER BY field DESC;
Cependant, ce n » t travailler si le résultat total est de, disons 60 lignes. La requête interne renvoie 60 lignes parce que c'est dans le top 75. Ensuite, la requête externe renvoie les lignes 35-60, qui ne rentre pas dans la "page" souhaitée de 50-75. Fondamentalement, cette solution fonctionne à moins que vous ayez besoin de la dernière "page" d'un ensemble de résultats qui ne soit pas un multiple de la taille de la page.
Edit:
Une autre solution fonctionne mieux, mais seulement si vous pouvez supposer le jeu de résultats comprend une colonne unique:
SELECT TOP n *
FROM tablename
WHERE key NOT IN (
SELECT TOP x key
FROM tablename
ORDER BY key
);
Conclusion:
Aucun général solution semble exister pour émuler LIMIT
dans MS SQL Server 2000. Une bonne solution existe si vous pouvez utiliser la fonct ROW_NUMBER()
ion dans MS SQL Server 2005.
Oui, c'est proche, mais il ne fonctionne que quand il y a une clé unique dans le résultat de la requête provisoire. Comment le feriez-vous dans une requête GROUP BY ou pour une requête qui rejoint plusieurs tables? –