Enigma su case when

venerdì 22 maggio 2009 - 13.03

arius Profilo | Newbie

Ciao
è da 2 giorni che vorrei risolvere questo enigma ma da sola non riesco:
che differenza c'è tra queste due espressioni perchè io non ne vedo ma in realtà ci sono perchè ottengo risultati diversi

1°espressione
UPDATE DT_FRAGILONI_2008
SET SAD='1'
FROM DT_SERVITI_FLUSSO_08
WHERE (DT_FRAGILONI_2008.ID_ANAGRAFE=DT_SERVITI_FLUSSO_08.ID_ANAGRAFE) AND (RAG_SERVIZI='1')
UPDATE DT_FRAGILONI_2008
SET SAD= '0'
WHERE (SAD IS NULL)

2°espressione
UPDATE DT_FRAGILONI_2008
SET SAD= CASE WHEN (RAG_SERVIZI='1') THEN '1' ELSE '0' END
FROM DT_SERVITI_FLUSSO_08
WHERE DT_FRAGILONI_2008.ID_ANAGRAFE=DT_SERVITI_FLUSSO_08.ID_ANAGRAFE

grazie!!!!

alx_81 Profilo | Guru

>Ciao
ciao
>1°espressione
>UPDATE DT_FRAGILONI_2008
>SET SAD='1'
>FROM DT_SERVITI_FLUSSO_08
>WHERE (DT_FRAGILONI_2008.ID_ANAGRAFE=DT_SERVITI_FLUSSO_08.ID_ANAGRAFE)
>AND (RAG_SERVIZI='1')
>UPDATE DT_FRAGILONI_2008
>SET SAD= '0'
>WHERE (SAD IS NULL)
>
>2°espressione
>UPDATE DT_FRAGILONI_2008
>SET SAD= CASE WHEN (RAG_SERVIZI='1') THEN '1' ELSE '0' END
>FROM DT_SERVITI_FLUSSO_08
>WHERE DT_FRAGILONI_2008.ID_ANAGRAFE=DT_SERVITI_FLUSSO_08.ID_ANAGRAFE

Sei sicura che i record in cui SAD IS NULL corrispondano a quelle non aggiornate?
Non vorrei che qualche SAD fosse in realtà una stringa vuota..
Comunque, in questi casi, è buona cosa che passi qualche insert di esempio e i resultset diversi che ottieni..

>grazie!!!!
di nulla!
--

Alessandro Alpi | SQL Server MVP

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi
http://italy.mvps.org

arius Profilo | Newbie

Ho rifatto il programma con con due tabelle di esempio:
la prima si chiama dati
id num prova
1 25 0
2 31 0
3 5 0
4 48 0
5 26 0
6 38 0
7 79 0
8 69 0
9 51 0
10 20 0
11 21 0
12 18 0
13 35 0
14 21 0
15 13 0

la seconda è dati_dett
id num unico1
1 25 ari
1 26 ari
1 25 fra
1 31 fra
2 31 fra
2 55 lino
3 55 lino
3 5 fra
4 48 ari
5 26 ari
6 38 ari
6 20 fra
6 20 fra
7 21 fra
7 79 fra
8 69 lino
8 20 ari
8 58 ari
9 29 ari
9 35 fra
9 36 fra
9 48 lino
9 51 lino
10 20 lino
11 21 ari
12 18 ari
12 46 fra
12 24 ari
13 27 lino
13 35 lino
14 21 ari
15 13 lino

UPDATE dati
SET
prova= case when (unico2='ari') then '1' else '0' end
FROM dati_dett
WHERE (dati.id=dati_dett.id)

il risultato nella tabella dati campo prova:
id num prova
1 25 1
2 31 0
3 5 0
4 48 1
5 26 1
6 38 1
7 79 0
8 69 0
9 51 0
10 20 0
11 21 1
12 18 1
13 35 0
14 21 1
15 13 0

se noti nell'id 9 il valore di prova dovrebbe essere 1 perchè contiene 'ari' ma invece mi dà 0
Come mai????

alx_81 Profilo | Guru

ciao, nonostante il ritardo, provo a risponderti. La prossima volta, passaci proprio le insert e le create delle tabelle, così ci faciliti la celerità della risposta.

>se noti nell'id 9 il valore di prova dovrebbe essere 1 perchè
>contiene 'ari' ma invece mi dà 0
>Come mai????
Quello che affermi non è corretto. Se provi infatti a fare la SELECT corrispondente alla tua update, in questo modo:

select *,case when (unico1='ari') then '1' else '0' end FROM dati_dett, dati WHERE (dati.id=dati_dett.id)

oppure scritta anche così, forse più comprensibile:

SELECT * , case when (unico1='ari') then '1' else '0' end FROM dbo.dati D JOIN dbo.dati_dett DD ON D.id = DD.id

otterrai questo risultato:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra
[/code]10 20 0 10 20 lino 0
11 21 0 11 21 ari 1
12 18 0 12 18 ari 1
12 18 0 12 46 fra 0
12 18 0 12 24 ari 1
13 35 0 13 27 lino 0
13 35 0 13 35 lino 0
14 21 0 14 21 ari 1
15 13 0 15 13 lino 0
[/code]
dove hai id = 9 e quindi qui:
9 51 0 9 29 ari 1 9 51 0 9 35 fra 0 9 51 0 9 36 fra 0 9 51 0 9 48 lino 0 9 51 0 9 51 lino 0

noterai che solo dove il tuo record di dettaglio contiene ari il valore è 1 per la colonna definita nel CASE.
Siccome però fai l'update SOLO sull'id, il tuo 1 viene sovrascritto col resto del resultset.
In realtà la tua update aggiorna con l'ultimo verificato un set di righe.
Il comportamento è del tutto corretto..

Se tu vuoi impostare a 1 la colonna solo se ALMENO uno dei record di dettaglio è valorizzato ad 'ari', devi fare una update in cui ricavi gli id che hanno almeno una volta 'ari', come in questo esempio:

UPDATE dbo.dati SET prova = case when (unico1='ari') then '1' else '0' end FROM dbo.dati D LEFT JOIN dbo.dati_dett DD ON D.id = DD.id AND DD.unico1 = 'ari'

In questo caso aggiorni a 0 ovunque non si verifichi il legame e ad 1 quando compare per un id almeno un dettaglio valorizzato ad 'ari'.

Ciao!
--

Alessandro Alpi | SQL Server MVP

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi
http://italy.mvps.org
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5