0
votes

Dates et jointures croisées dans Oracle SQL

J'utilise Oracle SQL et je rencontre un problème à l'aide de jointures croisées. J'ai une table, des services, qui a des dates de démarrage et de fin pour un service: xxx

J'ai besoin de convertir ce tableau en ce qui suit: xxx

essentiellement, j'ai besoin d'une ligne par jour, plutôt que d'une plage de dates. Mon approche actuelle est la suivante. J'ai une autre table, date_time, avec des dates, par exemple xxx

et je fais le suivant xxx

le problème que Je suis en cours d'exécution, c'est que cela fonctionne douloureusement lentement comme en réalité, j'ai un ensemble de données beaucoup plus grand. Y a-t-il un moyen plus efficace de faire cela qui me manque?

merci!


1 commentaires

Quel est le plan d'exécution? Quels indices existent sur les tables?


3 Réponses :


1
votes

Vous n'êtes pas sûr si cela vous aidera, mais chaque fois que vous avez à la fois un croix rejoindre et un où la clause avec des conditions utilisant des éléments des deux tables, vous pouvez réécrire cela à utiliser. Un rejoindre interne à la place ... et parfois la base de données peut alors déduire un meilleur plan d'exécution.

Encore une fois, je ne peux pas prédire si cela aidera dans votre situation, mais quand cela aidera l'amélioration est généralement centrée sur la fabrication d'une meilleure utilisation des indices , où le rejoint < / code> ignoré un index utile pour filtrage les résultats et choisissez un indice mieux pour commande les résultats, ou que couvre tous les champs tous les champs utilisé, en raison d'une hypothèse que chaque enregistrement de la table serait utilisé.

et en parlant d'index, si cela n'aide pas à voir la prochaine chose à regarder. Mais puisque nous ne savons pas quels indices vous avez déjà, tout ce que je suggère ici serait un coup de nuit.


0 commentaires

1
votes

Vous n'avez pas besoin d'utiliser la table date_time code> et a rejoindre code>; Au lieu de cela, vous pouvez utiliser une clause de facteur de sous-requête récursive (reconsive avec la clause code>) pour générer les lignes suivantes:

SRVC     | DATE     
:------- | :--------
Baseball | 15-FEB-20
Baseball | 16-FEB-20
Baseball | 17-FEB-20
Baseball | 18-FEB-20
Baseball | 19-FEB-20
Baseball | 20-FEB-20
Therapy  | 01-JAN-20
Therapy  | 02-JAN-20
Therapy  | 03-JAN-20
Therapy  | 04-JAN-20
Therapy  | 05-JAN-20


2 commentaires

Merci pour l'aide avec ça! Un suivi rapide, toute chance que vous puissiez me dire comment modifieriez-vous votre solution si la fin était NULL pour une rangée et la date la plus récente serait la date actuelle? Par exemple, j'ai commencé mon service le 18 juillet et je suis toujours inscrit (c'est-à-dire aucune date de fin), alors j'aurais quatre rangées (18 juillet 19, 20 et 21) avec le dernier numéro étant la date de cette publication


@DJC au lieu de "fin" sur la ligne 4, utilisez coalesce ("fin", sysdate) .



1
votes

Pas besoin d'une table de calendrier distincte ici. Au lieu de cela, utilisez connectez-vous par niveau : xxx

étant donné que les données de test que vous avez fournies produisent le résultat xxx

DB <> Fiddle ici


1 commentaires

N'est-ce pas extrêmement inefficace lorsque vous avez plusieurs rangées d'entrée et de grandes gammes? Pour chaque ligne d'entrée, il générera une ligne lorsque le niveau de niveau = 1 puis, à niveau = 2 , le nombre de lignes sera carré car il n'y a pas de corrélation pour chaque niveau = 1 la ligne sera enraûté en corrélation en corrélation d'un niveau = 2 , puis au niveau niveau = 3 Le nombre de lignes sera cube et à Chaque niveau Le nombre de lignes se développera de manière exponentielle, puis distinct sera appliqué pour supprimer un nombre énorme de lignes. DB <> Fiddle