Domanda

C'è un modo per riscrivere un'istruzione Transact SQL che utilizza un caso in cui la struttura a fare lo stesso senza utilizzare il caso quando?

Io sto usando un prodotto che ha un Progettazione query built-in e la propria pseudo-SQL. Ha limitazioni su quello che posso utilizzare con SQL Server e Oracle. Quindi ho questa colonna che, quando il database sottostante è Oracle, utilizza DECODE (che è supportato). Tuttavia, ho bisogno di farlo funzionare con SQL Server e custodia quando non è supportato.

L'affermazione che sto cercando di convertire è qualcosa di simile

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')

Ho un insieme limitato di opzioni T-SQL da usare e custodia quando non è un'opzione. Io ho IsNull e Coalesce, ma non sono sicuro se mi aiuterà con questo.

Non perdete tempo con i calcoli di data, quelli sono risolti.

Ho cercato il caso in cui le domande qui, senza alcun risultato.

Grazie!

Aggiornamento:

Mi rendo conto che avrei dovuto dare maggiori dettagli sul motivo per le limitazioni, in quanto si tratta di risorse di uno sviluppatore e sarebbe presumere che questo è un prodotto di sviluppo. Non è.

Sto usando un prodotto di software enterprise che ha una Progettazione query built-in e la propria pseudo-SQL. Ha limitazioni su quello che posso utilizzare con SQL Server e Oracle. In pratica, tutto ciò che non si rompe l'analisi del motore di query integrato è un gioco. Ciò significa che tutte le funzioni sanzionati e le espressioni, oltre a tutte le astrazioni di dati (oggetti interni, che corrispondono a una tabella fisica in un database e altre query create con il prodotto), più tutto da Oracle SQL o Transact SQL che non si rompe in modo esplicito il parsing .

Il motivo per cui CASO QUANDO non funziona per me è che si rompe l'analisi dello pseudo-SQL dal motore di ricerca.

In definitiva, vorrei cercare di:

  1. Utilizzare solo interrogazione del prodotto progettista l'SQL che passa il parsing OR
  2. Usa un paio di risorse aggiuntive da il database SQL Server e il Progettazione query per avere fatto.

In base alle diverse buone risposte che ho ottenuto, ecco l'approccio che ha funzionato per me, finora.

Jason DeFontes ha suggerito che potrei usare una vista di database per eseguire il caso in cui le regole e che rientra nella sopra # 2. Funziona per me, perché la vista è abbastanza dinamica che io non devo fare manutenzione su di essa (in contrasto con l'approccio tabelle di verità di richartallent, che a mio avviso sono vicini all'approccio di Jason). il suggerimento di Pascal di creazione di una funzione sarebbe andato lungo le stesse linee, ma probabilmente rompere il parsing.

Così ho creato una vista di database che fa tutto la trasformazione con CASO QUANDO ed ho aggiunto a SQL di mia domanda, unito con lo SQL esistente e ha funzionato bene. Mi rendo conto che probabilmente sto aggiungendo un overhead per il motore di database, in quanto dovrà recuperare gli stessi set di dati due volte (una per la vista e uno per la query), ma è uno di quei casi in cui non è certo un problema.

Dato che questo "utilizzare al fine di offuscare lo" progetto funziona per me, mi chiedo quale sarebbe il metodo più efficace:

  • Utilizzo di una SELECT con CASO QUANDO;
  • Uso CTE (di nuovo, richardtallent);
  • Uso Union Tutti (HLGEM);
  • utilizzando sottoquery (MisterZimbu);

sarò ancora controllare il suggerimento di Aramis Wyler, in quanto potrebbe probabilmente cadere in sopra 1 #.

Per il momento, la risposta di Jason è stato accettato. Considerando che ho usato CASO QUANDO nella vista, forse il titolo per la questione ha finito per essere è mal scelto. Ho aumentato a tutti che ha suggerito qualcosa che ha aiutato nel processo. Non so se questo fa la differenza nella vostra reputazione o no, ma ho pensato che fosse la cosa bella da fare.

Ancora una volta, voglio ringraziare tutti voi per il vostro aiuto e vi chiedo gentilmente di modificare nulla sulla questione che sei caduto non è appropriato (è la mia prima domanda e l'inglese è la mia seconda lingua).

È stato utile?

Soluzione

Si può spostare il CASO / quando la logica in una vista, poi la query strumento della vista?

Altri suggerimenti

Hai unione tutti disponibili? Forse si potrebbe scrivere una query per ciascuna delle condizioni con la condizione del caso inthe dove clausola e li unione insieme.

Si può scrivere subquery personalizzati? Probabilmente non se non si hanno nemmeno bisogno l'accesso a CASO QUANDO, ma questo sarebbe probabilmente lavorare troppo:

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>

scriva una funzione che esegue il calcolo utilizzando CASO QUANDO.

E 'brutto e in funzione del numero di valori avete potrebbe non essere praticabile. Ma a rigor di termini, credo che qualcosa di simile potrebbe funzionare come una traduzione dal segmento query precedente:

selezionare 'PastDue' dal nometabella dove Now ()> TargetDateColumn e (StatusColumn = 'valore 1' o StatusColumn = 'Valore 2' o StatusColumn = 'Valore 3')   union select 'eccezionale', dove Now ()

Non sono esattamente sicuro di aver capito il tuo codice, ma questo dovrebbe darvi un'idea per un approccio diverso.

In primo luogo, creare una tabella:

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

Ora, popolarlo con una tabella di verità (un sacco di logica ripetuto a qui a quanto pare, forse questo dovrebbe essere di due tabelle di verità con una croce JOIN tra di loro):

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')

Infine, unire e fornire una risposta predefinita:

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

Un vantaggio chiave di questo approccio è che mette la logica di business in tabelle di dati, non di codice, che è spesso più mantenibile ed estensibile.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top