Question

Y at-il un moyen de réécrire une instruction Transact SQL qui utilise un cas où la structure de faire la même chose sans utiliser le CAS QUAND?

J'utilise un produit qui a un concepteur de requêtes intégré et son propre pseudo-SQL. Il a des limites sur ce que je peux utiliser avec SQL Server et Oracle. J'ai donc cette colonne que, lorsque la base de données sous-jacente est Oracle, utilise decode (qui est pris en charge). Cependant, je dois le faire fonctionner avec SQL Server et CASE WHEN ne sont pas pris en charge.

La déclaration que je suis en train de convertir est quelque chose comme

Decode (StatusColumn,  'Value 1',
Decode(Sign(Now()-TargetDateColumn)),1,'Past
Due', 'Outstanding'),  'Value 2',
Decode(Sign(Now()-TargetDateColumn)),1,'Past
Due', 'Outstanding'),  'Value 3',
Decode(Sign(Now()-TargetDateColumn)),1,'Past
Due', 'Outstanding'),  'Value 4')

J'ai un nombre limité d'options T-SQL à utiliser et CASE WHEN est pas une option. Je n'ai IsNull et Coalesce, mais je ne sais pas s'ils me aider avec celui-ci.

Ne vous embêtez pas avec les calculs de date, ceux-ci sont résolus.

Je cherchai le cas lorsque des questions ici, en vain.

Merci!

Mise à jour:

Je me rends compte que je aurais dû donner plus de détails sur la raison des limites, car cela est la ressource d'un développeur et il serait supposer que c'est un produit de développement. Il n'est pas.

J'utilise un logiciel d'entreprise qui a un concepteur de requêtes intégré et son propre pseudo-SQL. Il a des limites sur ce que je peux utiliser avec SQL Server et Oracle. En fait, tout ce qui ne casse pas l'analyse du moteur de recherche intégré est un jeu. Cela signifie que toutes les fonctions sanctionnées et expressions, ainsi que toutes les abstractions de données (objets internes qui correspondent à une table physique dans une base de données et d'autres requêtes créées avec le produit), ainsi que tout d'Oracle SQL ou Transact SQL qui ne casse explicitement l'analyse syntaxique .

La raison pour laquelle CASE WHEN ne fonctionne pas pour moi est qu'il casse l'analyse syntaxique du pseudo-SQL par le moteur de recherche.

En fin de compte, je voudrais essayer de:

  1. Utilisez uniquement la requête de produit concepteur SQL qui passe la parser, ou
  2. Utilisez quelques ressources supplémentaires de la base de données SQL Server et le concepteur de requêtes pour le faire.

Sur la base de plusieurs bonnes réponses que je tiens, voici l'approche qui a fonctionné pour moi, à ce jour.

Jason DeFontes a suggéré que je pouvais utiliser une vue de base de données pour effectuer le cas lorsque les règles et qui tombe dans 2 ci-dessus. Il travaille pour moi parce qu'une vue est assez dynamique que je ne dois pas faire l'entretien sur elle (par opposition aux tables de vérité de richartallent approche, que je crois sont proches de l'approche de Jason). La suggestion de Pascal de créer une fonction irait dans le même sens, mais sans doute briser l'analyse syntaxique.

Je créé une vue de base de données qui fait toute la transformation CASE QUAND et je l'ai ajouté à la SQL de ma requête, a rejoint avec le SQL existant et cela a fonctionné très bien. Je me rends compte que je suis probablement ajouter une surcharge du moteur de base de données, car il devra récupérer les mêmes ensemble de données deux fois (un pour la vue et l'autre pour la requête), mais il est l'un de ces cas où il est à peine un problème.

Étant donné que cette « utilisation en vue de masquer ce » conception fonctionne pour moi, je me demande quelle serait l'approche plus efficace:

  • En utilisant une sélection avec CASE QUAND;
  • Utilisation de CTE (encore une fois, richardtallent);
  • Utilisation de l'Union Tous (HLGEM);
  • Utilisation des sous-requêtes (MisterZimbu);

Je vais quand même vérifier la suggestion d'Aramis Wyler, car il pourrait probablement tomber dans 1 ci-dessus.

Pour l'instant, la réponse de Jason a été acceptée. Considérant que je CASE WHEN dans la vue, peut-être le titre de la question a fini par être est mal choisi. Je suggère que tout le monde haussé quelque chose qui a aidé dans le processus. Je ne sais pas si cela fait une différence dans votre réputation ou non, mais je pensais que c'était la bonne chose à faire.

Encore une fois, je tiens à vous remercier tous pour votre aide et vous demander de bien vouloir modifier quoi que ce soit sur la question que vous tombiez ne convient pas (c'est ma première question et l'anglais est ma langue seconde).

Était-ce utile?

La solution

Pouvez-vous déplacer le CAS / QUAND logique en vue, alors la requête d'outils de la vue?

Autres conseils

Avez-vous l'union tous disponibles? Peut-être que vous pourriez écrire une requête pour chacune des conditions de l'état de l'affaire INTHE où la clause et de l'union ensemble.

Pouvez-vous écrire les sous-requêtes personnalisées? Probablement pas si vous n'avez même pas accès à CASE QUAND, mais cela marcherait probablement aussi:

select
    ...,
    coalesce(c1.value, c2.value, c3.value, ..., <default value>)
from MyTable
left join (select <result 1> as value) c1 on <first condition>
left join (select <result 2> as value) c2 on <second condition>
left join (select <result 3> as value) c3 on <third condition>

Ecrire une fonction qui effectue avec CASE lorsque le calcul.

Il est laid et en fonction du nombre de valeurs que vous avez peut ne pas être viable. Mais à proprement parler, je pense que quelque chose comme cela fonctionnerait comme une traduction du segment de requête ci-dessus:

sélectionner 'PastDue' de tablename où Maintenant ()> TargetDateColumn et (StatusColumn = 'Valeur 1' ou StatusColumn = 'Valeur 2' ou StatusColumn = 'Valeur 3')   union select 'exceptionnelle' où maintenant ()

Je ne suis pas sûr que je comprends votre code, mais cela devrait vous donner une idée d'une approche différente.

Tout d'abord, créez une table:

CREATE TABLE StatusLookup(
   value nvarchar(255),
   datesign shortint,
   result varchar(255));

Maintenant, le remplir avec une table de vérité (beaucoup de logique répétée dans ici apparemment, peut-être cela devrait être deux tables de vérité avec une jointure croisée entre eux):

INSERT INTO StatusLookup(value, datesign, result) VALUES ('Value 1', -1, 'Outstanding')
INSERT INTO StatusLookup(value, datesign, result) VALUES ('Value 1', 0, 'Outstanding')
INSERT INTO StatusLookup(value, datesign, result) VALUES ('Value 1', 1, 'Past Due')
INSERT INTO StatusLookup(value, datesign, result) VALUES ('Value 2', -1, 'Outstanding')
INSERT INTO StatusLookup(value, datesign, result) VALUES ('Value 2', 0, 'Outstanding')
INSERT INTO StatusLookup(value, datesign, result) VALUES ('Value 2', 1, 'Past Due')
INSERT INTO StatusLookup(value, datesign, result) VALUES ('Value 3', -1, 'Outstanding')
INSERT INTO StatusLookup(value, datesign, result) VALUES ('Value 3', 0, 'Outstanding')
INSERT INTO StatusLookup(value, datesign, result) VALUES ('Value 3', 1, 'Past Due')

Enfin, joignez-vous et fournir une réponse par défaut:

SELECT mytable.*, COALESCE(statuslookup.result, 'Value 4')
FROM
    mytable LEFT JOIN statuslookup ON
        statuslookup.value = StatusColumn
        AND statuslookup.datesign = Sign(Now()-TargetDateColumn)

L'un des principaux avantages de cette approche est qu'elle met la logique métier dans les tableaux de données, pas de code, qui est souvent plus maintenable et extensible.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top