J'ai du mal à convertir des procédures stockées de SQL Server vers Oracle pour que notre produit soit compatible avec celui-ci.
J'ai des requêtes qui renvoie l'enregistrement le plus récent de certaines tables, basé sur un horodatage:
Serveur SQL:
SELECT TOP 1 *
FROM RACEWAY_INPUT_LABO
ORDER BY t_stamp DESC
=> Cela me retournera l'enregistrement le plus récent
Mais Oracle:
SELECT *
FROM raceway_input_labo
WHERE rownum <= 1
ORDER BY t_stamp DESC
=> Cela me rendra l'enregistrement le plus ancien (probablement en fonction de l'index), quelle que soit la ORDER BY
déclaration!
J'ai encapsulé la requête Oracle de cette façon pour répondre à mes besoins:
SELECT *
FROM
(SELECT *
FROM raceway_input_labo
ORDER BY t_stamp DESC)
WHERE rownum <= 1
et il fonctionne. Mais cela me semble un horrible hack, surtout si j'ai beaucoup de disques dans les tables concernées.
Quelle est la meilleure façon d'y parvenir?
sql
oracle
sql-order-by
rownum
Larry
la source
la source
Réponses:
L'
where
instruction est exécutée avant leorder by
. Ainsi, votre requête désirée dit " prenez la première ligne et triez-la ensuite part_stamp
desc ". Et ce n'est pas ce que vous entendez.La méthode de sous-requête est la méthode appropriée pour ce faire dans Oracle.
Si vous souhaitez une version qui fonctionne sur les deux serveurs, vous pouvez utiliser:
L'extérieur
*
renverra "1" dans la dernière colonne. Vous auriez besoin de lister les colonnes individuellement pour éviter cela.la source
Utilisez
ROW_NUMBER()
plutôt.ROWNUM
est une pseudo-colonne etROW_NUMBER()
est une fonction. Vous pouvez en savoir plus sur la différence entre eux et voir la différence de sortie des requêtes ci-dessous:la source
ROWNUM
pourrait être plus rapide queROW_NUMBER()
si l'un doit ou non utiliser l'un sur l'autre dépend d'un certain nombre de facteurs.Une alternative que je suggérerais dans ce cas d'utilisation est d'utiliser le MAX (t_stamp) pour obtenir la dernière ligne ... par exemple
Ma préférence de modèle de codage (peut-être) - fiable, fonctionne généralement à ou mieux que d'essayer de sélectionner la 1ère ligne dans une liste triée - également l'intention est plus explicitement lisible.
J'espère que cela t'aides ...
SQLer
la source
Quelques problèmes de conception documentés avec cela dans un commentaire ci-dessus. Petite histoire, dans Oracle, vous devez limiter les résultats manuellement lorsque vous avez de grandes tables et / ou des tables avec les mêmes noms de colonne (et que vous ne voulez pas les taper explicitement et les renommer toutes). La solution simple consiste à déterminer votre point d'arrêt et à le limiter dans votre requête. Vous pouvez également le faire dans la requête interne si vous n'avez pas la contrainte de noms de colonnes en conflit. Par exemple
réduira considérablement les résultats. Ensuite, vous pouvez ORDER BY ou même effectuer la requête externe pour limiter les lignes.
De plus, je pense que TOAD a une fonctionnalité pour limiter les lignes; mais, pas sûr que cela limite la requête réelle sur Oracle. Pas certain.
la source