Lorsque j'ai travaillé sur le Zend Framework composant de base de données, nous avons essayé de résumé de la fonctionnalité de l' LIMIT
clause supportés par MySQL, PostgreSQL et SQLite. Qui est, la création d'une requête pourrait être fait de cette façon:
$select = $db->select();
$select->from('mytable');
$select->order('somecolumn');
$select->limit(10, 20);
Lorsque la base de données prend en charge LIMIT
, ce qui 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 qui ne permettent pas d' LIMIT
(cette clause ne fait pas partie de la norme SQL de la langue, par la voie). Si vous pouvez générer des numéros de ligne, faire de l'ensemble de la requête d'une table dérivée, et dans la requête externe utiliser BETWEEN
. C'était la solution pour Oracle et IBM DB2. Microsoft SQL Server 2005 a une semblable ligne-numéro de la fonction, 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 @offset+@count;
Toutefois, Microsoft SQL Server 2000 n'a pas l' ROW_NUMBER()
fonction.
Donc ma question est, pouvez-vous trouver un moyen pour émuler l' LIMIT
de fonctionnalités dans Microsoft SQL Server 2000, uniquement à l'aide de SQL? Sans l'aide de curseurs ou T-SQL ou une procédure stockée. Il a à soutenir à la fois les arguments pour LIMIT
, les deux nombre et de décalage. Les Solutions à l'aide d'une table temporaire ne sont pas acceptables.
Edit:
La solution la plus courante pour MS SQL Server 2000 semble être comme celui ci-dessous, par exemple, pour obtenir les lignes 50 à 75:
SELECT TOP 25 *
FROM (
SELECT TOP 75 *
FROM table
ORDER BY BY field ASC
) a
ORDER BY field DESC;
Toutefois, cela ne fonctionne pas si le jeu de résultats total est, disons 60 lignes. L'intérieur de la requête retourne 60 lignes parce que c'est dans le top 75. Alors que l'extérieur de la requête renvoie des lignes 35-60, qui ne rentre pas dans la "page" de 50 à 75. Fondamentalement, cette solution fonctionne, sauf si vous avez besoin de la dernière "page" d'un ensemble de résultats qui n'arrive pas à être un multiple de la taille de la page.
Edit:
Une autre solution fonctionne mieux, mais seulement si vous pouvez assumer le résultat inclut une colonne unique en son genre:
SELECT TOP n *
FROM tablename
WHERE key NOT IN (
SELECT TOP x key
FROM tablename
ORDER BY key
);
Conclusion:
Aucune solution ne semble exister pour l'émulation LIMIT
de MS SQL Server 2000. Une bonne solution existe si vous pouvez utiliser l' ROW_NUMBER()
fonction dans MS SQL Server 2005.