Principale utente con più risposte
Migrazione ACCESS -> SQL Server - FUNZIONI LAST/FIRST

Domanda
-
Ciao, ho un problema durante la migrazione da ACCESS a SQL SERVER 2008 R2
Devo portare due query aventi funzioni last / first in viste SQL Server ma non riesco a convertirne le funzioni.
Posto le due query:
PRIMA
SELECT Sinistri_Attivita.IDSinistro, Last(Sinistri_Attivita.Data) AS Data, Count(Sinistri_Attivita.Attività) AS Totale_Attivita, Last(Sinistri_Attivita.Attività) AS Attivita FROM Sinistri_Attivita GROUP BY Sinistri_Attivita.IDSinistro;
SECONDA
SELECT Sinistri_Attivita.IDSinistro, First(Sinistri_Attivita.Riserva) AS Riserva, Last(Sinistri_Attivita.Attività) AS Attività, Last(Sinistri_Attivita.Data) AS [Ultima Data] FROM Sinistri_Attivita GROUP BY Sinistri_Attivita.IDSinistro ORDER BY Sinistri_Attivita.IDSinistro;
Potete autarmi?
Ho provato con MIN/MAX ma senza risultato...
Risposte
-
Per i dati booleani SQL Server usa il tipo BIT, quando tu esegui una insert in un campo BIT inserendo i valori True e False, vengono rispettivamente accettati come 1 e 0.
Esegui questo blocco di codice per la dimostrazione pratica:
DECLARE @Table TABLE ( id INT IDENTITY (1,1) NOT NULL, bool BIT ) INSERT INTO @Table (bool) SELECT 0 ; INSERT INTO @Table (bool) SELECT 1 ; INSERT INTO @Table (bool) SELECT 'False' ; INSERT INTO @Table (bool) SELECT 'True' ; SELECT * FROM @Table ;
Per quanto riguarda il tuo software, credo che nella stragrande maggioranza dei linguaggi quando dichiari un tipo bool e lo popoli con un dato [ 0 - 1 ] o [ false - true ], il controllo rimanga equivalente..
fermo restando che tu non abbia usato un confronto di stringhe.. per spiegarmi meglio in pseudocodifica:
------------------------------------------------------------------------------------------------------------------
[ Caso 1 ]
-- Dichiari variabile bool : aBoolean
-- Popoli variabile "aBoolean" col valore : 1
-- Condizione corretta : if(aBoolean = true){ Verificata correttamente, confronti un tipo con un suo pari }
-- Condizione potenzialmente corretta : if(aBoolean = "true") { Viene eseguito un casting implicito e probabilmente funzionerà }
------------------------------------------------------------------------------------------------------------------
[ Caso 2 ]
-- Dichiari variabile stringa : aBoolean
-- Popoli variabile "aBoolean" col valore : 1
-- Condizione scorretta if(aBoolean == "true") { aBoolean viene castato a stringa, "1" è <> da "true" }
------------------------------------------------------------------------------------------------------------------
Se ho capito il caso.. :)
Tutte le risposte
-
Ciao, in SQL Server non c'è una conversione diretta di quelle funzioni, devi affidarti alla logica dell'interrogazione.
Per esempio, prendiamo un set di dati tabellari che contiene [n] righe, con due colonne: Id (INT), Utente (VARCHAR), UltimoAccesso (DATETIME) se vuoi che ti venga restituito l'ultimo valore del set di dati dovrai scrivere :
SELECT TOP 1 Id, Utente, UltimoAccesso FROM TuaTabella ORDER BY UltimoAccesso DESC ;
Per ottenere il first, è la stessa cosa ma con ordinamento finale al contrario (quindi ASC).
Un saluto
-
Ok ma nel mio caso devo solezionare più id ma tenere di essi solo l'ultima data e l'ultima attività.
Nel caso che mi hai scritto inoltre come faccio a eseguire un'interrogazione come la seconda (che contiene sia last che first)?
applico più Select?
SELECT tabella.ID, tab2.Data FROM tabella, (Select id top 1 Data FROM tabella as t order by ultimoAccesso Desc) where tabella.id = tab2.id
?
-
Da provare ma così potrebbe fungere, cambia il campo di ordinamento in base a quello che serve a te :
SELECT Sinistri_Attivita.IDSinistro, -- First(Sinistri_Attivita.Riserva) AS Riserva, (SELECT TOP 1 t1.Riserva FROM Sinistri_Attivita t1 WHERE t1.IDSinistro = t0.IDSinistro ORDER BY t1.CampoDiOrdinamento ASC) AS Riserva -- Last(Sinistri_Attivita.Attività) AS Attività, (SELECT TOP 1 t2.Attività FROM Sinistri_Attivita t2 WHERE t2.IDSinistro = t0.IDSinistro ORDER BY t1.CampoDiOrdinamento DESC) AS Attività Last(Sinistri_Attivita.Data) AS [Ultima Data] FROM Sinistri_Attivita t0 GROUP BY t0.IDSinistro ORDER BY t0.IDSinistro ;
- Modificato _ Luca Gaspari giovedì 11 aprile 2013 12:52
- Proposto come risposta _ Luca Gaspari martedì 16 aprile 2013 11:43
-
-
Problema... se io metto come mi dici tu mi da problema nella sintassi di ORDER.
Ho provato a fare solo la first e funge.
Se faccio due volte la first con alias diversi (riserva e riserva1) non funziona.
è come se accettasse solo una sotto select con campo order by ..
Come faccio?
-
-
-
Quello l'avevo fatto... avevo scordato la virgola tra un campo e l'altro della select :P ..
Ti chiedo solo una cosa... La query come mi hai detto tu funziona alla perfezione (entrambe le query).
Il problema è che nella mia mole di dati risulta LENTISSIMA... Qualche consiglio?
Grazie
-
Usa il Data Execution Plan per vedere come stà ragionando il tuo server quando risolve la query, vedi se stai sfruttando gli indici correttamente e se non lo stai facendo valuta la creazione di nuovi che ti permettano di lavorare più agilmente!
Ci sono sicuramente altri modi per scriverla (tipo joinare la tabella su se stessa includendo nella where la selezione dell'ultimo campo), ma quelli vanno valutati col piano di esecuzione.
Se vuoi saperne di più sul DEP, puoi iniziare da questo articolo della KB, ma dovrai studiarci un pochino per iniziare a capire come leggerlo e come ottimizzare le tue query di conseguenza (:
-
Ultima domanda... dato che sto effettuando una migrazione, e che il software che interrogherà SQL Server è già scritto (e parecchio grande) ti chiedo:
dato che il software accettava dati binari nella forma TRUE/FALSE, c'è modo di "trasformare" i miei dati in tabelle di SLQ SERVER in formato bin 1/0 in TRUE/FALSE ?
premetto che a volte le interrogazioni del mio software sono dirette alle tabelle senza passare per viste.
Grazie..
- Modificato Revan1988 giovedì 11 aprile 2013 17:15
-
Per i dati booleani SQL Server usa il tipo BIT, quando tu esegui una insert in un campo BIT inserendo i valori True e False, vengono rispettivamente accettati come 1 e 0.
Esegui questo blocco di codice per la dimostrazione pratica:
DECLARE @Table TABLE ( id INT IDENTITY (1,1) NOT NULL, bool BIT ) INSERT INTO @Table (bool) SELECT 0 ; INSERT INTO @Table (bool) SELECT 1 ; INSERT INTO @Table (bool) SELECT 'False' ; INSERT INTO @Table (bool) SELECT 'True' ; SELECT * FROM @Table ;
Per quanto riguarda il tuo software, credo che nella stragrande maggioranza dei linguaggi quando dichiari un tipo bool e lo popoli con un dato [ 0 - 1 ] o [ false - true ], il controllo rimanga equivalente..
fermo restando che tu non abbia usato un confronto di stringhe.. per spiegarmi meglio in pseudocodifica:
------------------------------------------------------------------------------------------------------------------
[ Caso 1 ]
-- Dichiari variabile bool : aBoolean
-- Popoli variabile "aBoolean" col valore : 1
-- Condizione corretta : if(aBoolean = true){ Verificata correttamente, confronti un tipo con un suo pari }
-- Condizione potenzialmente corretta : if(aBoolean = "true") { Viene eseguito un casting implicito e probabilmente funzionerà }
------------------------------------------------------------------------------------------------------------------
[ Caso 2 ]
-- Dichiari variabile stringa : aBoolean
-- Popoli variabile "aBoolean" col valore : 1
-- Condizione scorretta if(aBoolean == "true") { aBoolean viene castato a stringa, "1" è <> da "true" }
------------------------------------------------------------------------------------------------------------------
Se ho capito il caso.. :)