none
Migrazione ACCESS -> SQL Server - FUNZIONI LAST/FIRST RRS feed

  • 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...

    giovedì 11 aprile 2013 12:19

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.. :)

    • Contrassegnato come risposta Revan1988 martedì 16 aprile 2013 12:32
    • Contrassegno come risposta annullato Revan1988 martedì 16 aprile 2013 12:32
    • Contrassegnato come risposta Revan1988 martedì 16 aprile 2013 12:32
    giovedì 11 aprile 2013 17:46

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

    giovedì 11 aprile 2013 12:35
  • 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
    
    

    ?

    giovedì 11 aprile 2013 12:42
  • 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
    ;


    giovedì 11 aprile 2013 12:51
  • Ti ringrazio molto, provo e ti faccio sapere!

    Grazie davvero!

    giovedì 11 aprile 2013 13:06
  • 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?

    giovedì 11 aprile 2013 13:16
  • Trovato l'errore. Scusa! :)

    Funziona tutto! Grazie ancora!!!

    giovedì 11 aprile 2013 13:22
  • L'errore era che dovevi sostituire il campo di ordinamento con uno esistente (;

    Non c'è di che, flagga pure la risposta giusta come "Risposta al topic" per chiuderlo, alla prossima!

    giovedì 11 aprile 2013 13:25
  • 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

    giovedì 11 aprile 2013 13:42
  • 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 (:

    giovedì 11 aprile 2013 14:16
  • 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
    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.. :)

    • Contrassegnato come risposta Revan1988 martedì 16 aprile 2013 12:32
    • Contrassegno come risposta annullato Revan1988 martedì 16 aprile 2013 12:32
    • Contrassegnato come risposta Revan1988 martedì 16 aprile 2013 12:32
    giovedì 11 aprile 2013 17:46