Query sql (dinamico?) Per verificare che ogni voce di cronologia abbia una corrispondenza

StackOverflow https://stackoverflow.com/questions/8889496

  •  29-10-2019
  •  | 
  •  

Domanda

Ho una procedura memorizzata che sta generando un numero float casuale come marcatore ID e non appena viene chiamato memorizza il numero casuale + .1 in una tabella di cronologia/registrazione, quindi il risultato finale viene memorizzato con lo stesso casuale Numero +.2 (come sequencer/Sorter).

Esiste un modo semplice per interrogare dinamici una colonna piena di questi numeri di sequenza (come esaminato di seguito) e per verificare che ci siano un numero pari (coppie) per assicurarsi facilmente che la procedura memorizzata sia sempre stata elaborata correttamente?

1568.1
1568.2
8452.1
8452.2
9886.1
9886.2
5455.1
3682.1
3682.2
4857.1
4857.2

Nei dati di esempio sopra vorrei una query che avvisa alla presenza di 5455.1 in quanto non ha una seconda parte (5455,2) che dovrebbe sempre avere come log della procedura memorizzata una seconda voce con i risultati della chiamata (successo o fallimento).

Certo, ne ho bisogno non solo per avvisarmi che il problema/strano esiste (poiché potrei semplicemente eseguire un conteggio sul tavolo e vedere se il numero è persino per determinarlo), vorrei essere in grado di selezionare i disallineamenti Quindi non sto ordinando 10.000 righe di cronologia/tronchi per trovare quello che non ha un partner.

È stato utile?

Soluzione

Innanzitutto, il tuo key ID non dovrebbe essere una colonna, dovrebbe essere due. Cioè, invece di

CREATE TABLE OneCol  (IDKey DECIMAL(6, 1) Primary Key);

Dovresti avere qualcosa come:

CREATE TABLE TwoCol  
(
    IDRand INT, 
    PhaseID TINYINT
    Primary Key  (IDRand, PhaseID)
)

Supponendo questo quindi e inoltre che l'anomalia specifica che stai cercando è un ID con {fase = 1) ma nessun corrispondente {fase = 2} questo modo per scrivere la query:

SELECT IDRand FROM TwoCol WHERE PhaseID = 1
EXCEPT
SELECT IDRand FROM TwoCol WHERE PhaseID = 2

Altri suggerimenti

Ci scusiamo per la lunghezza qui, ma spero che possa aiutare la prossima persona che arriva ...

Come suggerito sopra, dividerò l'ID casuale in due campi: il primo con l'ID casuale e il secondo con l'ID "Fase". Usando l'istruzione TREST sopra funziona per restituire un elenco di ID casuali che sono stati avviati (esistono fase 1) ma mancano la seconda fase di completamento.

Tuttavia, dal momento che non voglio passare il tempo a cercare ogni liberazione singolarmente, ho avvolto l'istruzione tranne in una dichiarazione in Copiata di seguito. Questo mi permette di controllare quali campi vengono effettivamente restituiti.

SELECT randomid, phaseid, info, type, time
FROM history
WHERE randomid IN (
SELECT randomid FROM history WHERE phaseid = '1' 
EXCEPT 
SELECT randomid FROM history WHERE phaseid = '2'  
)

Nota: avvolgimento dell'istruzione TRANT come ho fatto risultati nella parte distinta (vedere il link sotto) che viene ignorato poiché sto specificando per selezionare tutto. Inoltre, dovrò migliorare il mio intervallo di numeri casuali o o aggiungerlo un codice di data per prevenire una duplicazione. Se mai mi fosse capitato di ottenere lo stesso numero casuale due volte, e se uno completato e uno fallito, quello che non ha fallito (non aveva una fase 2) non si sarebbe manifestato nei risultati della query di Trant Tener come l'esistenza di qualsiasi fase di completamento corrispondente soddisferà la clausola tranne. Non sta verificando che esiste una fase di completamento per ogni fase di partenza, solo che esiste affatto una fase di completamento con un ID casuale corrispondente.

Se avessi uno schema numerico scarsamente randomizzato che ha provocato duplicati, potrei avere 16 voci nella tabella con lo stesso ID casuale (diciamo che l'ID casuale è 1337). Il numero pari di voci con una liberazione di 1337 sembrerebbe a posto anche se potrei aver semplicemente avuto un numero pari di errori (verificare un conteggio uniforme delle voci nel database non è davvero un buon modo per verificare gli errori ora che penso Di esso, sebbene potrei contare il numero di ID di fase che sono 1 e confrontarlo con un conteggio di quelli con un PID di 2 al fine di verificare i risultati della mia query). Di quelle 16 voci, diciamo che 6 sono stati completati correttamente (Fase 1 e Fase 2) e i restanti 4 erano falliti in qualche modo. Poiché una voce nel database esisteva per RID 1337 con un PID di 2, nessuno dei 4 fallimenti sarebbe apparso.

Grazie per avermi indicato la giusta direzione, Barry!

========================================================

Il seguente collegamento sembrava andare un po 'più in profondità con gli esempi di tranne dell'operatore rispetto ad altri siti, nonostante fosse più vecchio (Statiung che vengono restituiti solo risultati distinti, rispetto a tutti i risultati).

http://www.databasejournal.com/features/mssql/article.php/3602601/except-operator-in-sql-server-2005.htm

========================================================

Generale di Pinal Dave riassunto dell'operatore:

Uno dei jr. Lo sviluppatore mi ha chiesto un giorno fa, SQL Server ha un funzionamento simile come la clausola meno in Oracle.

Assolutamente, tranne la clausola in SQL Server è esattamente simile all'operazione meno in Oracle. La query, tranne la query e meno la query, restituisce tutte le righe nella prima query che non vengono restituite nella seconda query. Ogni istruzione SQL all'interno della query tranne e meno deve avere lo stesso numero di campi nei set di risultati con tipi di dati simili.

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