J'ai une table dbo.X
avec DateTime
column Y
qui peut contenir des centaines d'enregistrements.
Ma procédure stockée a le paramètre @CurrentDate
, Je veux connaître la date dans le column Y
dans le tableau ci-dessus dbo.X
qui est inférieur et le plus proche de @CurrentDate.
Comment le trouver?
La clause where fera correspondre toutes les lignes avec une date inférieure à @CurrentDate et, comme elles sont classées par ordre décroissant, le TOP 1 sera la date la plus proche de la date actuelle.
SELECT TOP 1 *
FROM x
WHERE x.date < @CurrentDate
ORDER BY x.date DESC
Utilisez DateDiff et triez votre résultat en fonction du nombre de jours ou de secondes entre cette date et ce que l'entrée a été.
Quelque chose comme ça
select top 1 rowId, dateCol, datediff(second, @CurrentDate, dateCol) as SecondsBetweenDates
from myTable
where dateCol < @currentDate
order by datediff(second, @CurrentDate, dateCol)
J'ai une meilleure solution à ce problème, je pense.
Je vais montrer quelques images pour soutenir et expliquer la solution finale.
Contexte Dans ma solution, j'ai un tableau des taux de change. Ils représentent les taux du marché pour différentes devises. Cependant, notre fournisseur de services a eu un problème avec le flux de taux et, à ce titre, certains taux ont une valeur nulle. Je veux remplir les données manquantes avec des taux pour la même devise qui sont les plus proches dans le temps du taux manquant. Fondamentalement, je veux obtenir le RateId pour le taux non nul le plus proche que je remplacerai ensuite. (Ceci n'est pas montré ici dans mon exemple.)
1) Donc, pour commencer, identifions les informations de taux manquantes:
Requête montrant mes taux manquants, c'est-à-dire ayant une valeur de taux de zéro
2) Ensuite, identifions les taux qui ne manquent pas. Requête montrant les taux qui ne manquent pas
3) Cette requête est l'endroit où la magie opère. J'ai fait une hypothèse ici qui peut être supprimée mais a été ajoutée pour améliorer l'efficacité/les performances de la requête. L'hypothèse à la ligne 26 est que je m'attends à trouver une transaction de remplacement le même jour que celle de la transaction manquante/nulle. La magie opère est la ligne 23: la fonction Row_Number ajoute un numéro automatique commençant à 1 pour l'écart de temps le plus court entre la transaction manquante et non manquante. La prochaine transaction la plus proche a un rownum de 2, etc.
Veuillez noter qu'à la ligne 25, je dois joindre les devises afin de ne pas faire de différence entre les types de devises. C'est-à-dire que je ne veux pas remplacer une devise AUD par des valeurs CHF. Je veux les devises correspondantes les plus proches.
4) Enfin, permet d'obtenir des données où le RowNum est 1 La requête finale
La requête requête complète est la suivante;
; with cte_zero_rates as
(
Select *
from fxrates
where (spot_exp = 0 or spot_exp = 0)
),
cte_non_zero_rates as
(
Select *
from fxrates
where (spot_exp > 0 and spot_exp > 0)
)
,cte_Nearest_Transaction as
(
select z.FXRatesID as Zero_FXRatesID
,z.importDate as Zero_importDate
,z.currency as Zero_Currency
,nz.currency as NonZero_Currency
,nz.FXRatesID as NonZero_FXRatesID
,nz.spot_imp
,nz.importDate as NonZero_importDate
,DATEDIFF(ss, z.importDate, nz.importDate) as TimeDifferece
,ROW_NUMBER() Over(partition by z.FXRatesID order by abs(DATEDIFF(ss, z.importDate, nz.importDate)) asc) as RowNum
from cte_zero_rates z
left join cte_non_zero_rates nz on nz.currency = z.currency
and cast(nz.importDate as date) = cast(z.importDate as date)
--order by z.currency desc, z.importDate desc
)
select n.Zero_FXRatesID
,n.Zero_Currency
,n.Zero_importDate
,n.NonZero_importDate
,DATEDIFF(s, n.NonZero_importDate,n.Zero_importDate) as Delay_In_Seconds
,n.NonZero_Currency
,n.NonZero_FXRatesID
from cte_Nearest_Transaction n
where n.RowNum = 1
and n.NonZero_FXRatesID is not null
order by n.Zero_Currency, n.NonZero_importDate