Newsgroup: it.comp.software.database
Titolo: select per importi dare e avere uguali

ciao a tutti 
Allora io ho un database in access e sto lavorando in vb6
mi serve un aiutino
dovrei fare una select che mi selezioni tutti gli importi uguali DARE E
AVERE di ogni Singola Procedura per poi cancellarli
evitando però di selezionare e quindi cancellare gli importi che sono
uguali ma sono più di due...ad esempio nella tabella sottostante dovrei
lasciare gli importi 50 D,D,A della procedura RC
[CODE]importo  Segno  procedura  ID[/CODE] 
[CODE]500      D         SC       1[/CODE] 
[CODE]500      A         SC       2[/CODE] 
[CODE]300      D         SC       3[/CODE] 
[CODE]200      D         SC       4[/CODE] 
[CODE]580      D         MC       5[/CODE] 
[CODE]580      A         MC       6[/CODE]
[CODE]550      D         MC       7[/CODE] 
[CODE]5        A         MC       8[/CODE] 
[CODE]50       D         RC       9[/CODE] 
[CODE]550      D         RC       10[/CODE]  
[CODE]50       D         RC       9[/CODE] 
[CODE]550      A         RC       10[/CODE]  
[CODE]50       A         RC       9[/CODE] 
allora in questa tabella io devo selezionare per poi cancellare gli
importi 500 dare e avere dalla procedura SC
gli importi 580 dare e avere dalla proc MC e 550 RC
e lasciare tutti gli altri ma anche gli importi 50 D,A,D della procedura
RC perchè sono più di due importi uguali ...
ok???
spero di essere stato chiaro
mi aiutate???
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG

scusate
per gli ID naturalmente non sono ammessi duplicati
alla fine ho dimenticato di incrementarli



Ciao Fabrizio,
quello che non mi è chiaro è se vuoi eliminare le registrazioni con importi
uguali e che hanno saldo 0 o solo quelle con due importi uguali
Caso da eliminare Saldo=0 e righe =2
----------------
[CODE]500      D         SC       1[/CODE]
[CODE]500      A         SC       2[/CODE]
----------------
Caso da non eliminare saldo=50 e righe =3
--------------------
[CODE]50       D         RC       9[/CODE]
[CODE]50       D         RC       9[/CODE]
[CODE]50       A         RC       9[/CODE]
--------------------
se il controllo viene fatto solo sul numero di righe un caso del genere
andrebbe lasciato anche se ha saldo = 0
------------------------
[CODE]500      D         SC       1[/CODE]
[CODE]500      A         SC       2[/CODE]
[CODE]500      D         SC       3[/CODE]
[CODE]500      A         SC       4[/CODE]
----------------
mentre questo verrebbe eliminato anche se ha saldo<> da 0
------------------------
[CODE]500      D         SC       1[/CODE]
[CODE]500      D         SC       2[/CODE]
-----------------------
scoperto con quale criterio si devono selezionare le righe da cancellare è
semplice costruire una query di eliminazione.
Ciao Giorgio

dovrei eliminare tutto ciň che ha saldo 0 e che si riferisce a quella
procedura
esempio
se ho 
500 D  CC
500 A  CC
il saldo č 0 e quindi vanno eliminati
se ho 
500 D  SO
500 D  SO 
non va eliminato 
500 A  SO
500 D  SO
500 A  SO
non va eliminato
devo eliminare i due importi uguali dare e avere divisi per procedura
cioč se ho 500 D della procedura SO che si incrocia con 500 A della
procedura
CC non va ELIMINATO
mi aiuti??


se ho invece 500 D CC con 500 A cc 
va ELIMINATO perchè appartengono alla stessa procedura
cioè devo innanzitutto dividere tutte le procedure che ho
e per ogni procedura provvedere ad eliminare gli importi UGUALI Dare e
Avere
che portano a SALDO 0.
ok?



Ok,
visto che le quattro righe con saldo 0
------------------------
[CODE]500      D         SC       1[/CODE]
[CODE]500      A         SC       2[/CODE]
[CODE]500      D         SC       3[/CODE]
[CODE]500      A         SC       4[/CODE]
----------------
non le hai menzionate in quelle da cancellare allora  vanno lasciate quindi
serve un doppio controllo, uno sul saldo e uno sul numero di registrazioni.
Questa è la query per cancellare le righe doppie con saldo a 0
------------------------
DELETE *
FROM Tab
WHERE  DSum("IIF(Segno='A',-1,1)*Importo",
               "Tab",
                "Importo=" & Str([Importo]) & " AND procedura='" &
[Procedura] & "'") =0
     AND Dcount("1",
               "Tab",
               "Importo=" & Str([Importo]) & " AND procedura='" &
[Procedura] & "'") =2
------------------------
se vuoi solo vedere quelle che verranno cancellate sostituisci la DELETE con
SELECT.
Ho dovuto usare le funzioni Dsum e DCount perchè Access in presenza di
aggregazioni non permette la cancellazione dei record.
Ciao Giorgio


ne senso che:
questa query
--------------------------------
DELETE T
FROM   Tab T
   INNER JOIN
       (Select Importo,Procedura
        From Tab
        GROUP BY Importo,Procedura
        HAVING SUM(CASE SEGNO WHEN 'D' THEN Importo
                      WHEN 'A' THEN Importo * -1 END)=0
        AND COUNT(1)=2) T2
   ON T.Importo=T2.Importo AND T.Procedura=T2.Procedura
-----------------------------
modificata in modo opportuno per Access non può cancellare i record a causa
di una limitazione del motore del database.
per maggiori info
-------------------
ACC: Update Query Based on Totals Query Fails
http://support.microsoft.com/default.aspx?scid=kb;en-us;116142&Product=acc
------------------
Ciao Giorgio

come no
vanno cancellate
se ho 
500 D SC
500 A SC
500 D SC
500 A SC
vanno cancellate tutte , il problema è se sono dispari
non vanno cancellate se sono cosi
500 D VA
500 A VS
500 D CA
500 A VF
ok?
ho provato comunque ad adattare quello che hai scritto alla mia query
che sarebbe questa...CI (sarebbe la voce Procedura)
SELECT Agenzie.Dipendenza, Agenzie.CI, Storico.Importo, Storico.Segno,
Storico.ID_Part
FROM Agenzie INNER JOIN Storico ON Agenzie.ID = Storico.ID;
adattando la tua mi dà errore...
SELECT Agenzie.Dipendenza, Agenzie.CI, Storico.Importo, Storico.Segno,
Storico.ID_Part FROM Agenzie INNER JOIN Storico ON Agenzie.ID =
Storico.ID FROM
WHERE  DSum("IIF(Segno='A',-1,1)*Importo",
               "tab",
                "Importo=" & Str([Importo]) & " AND ci='" &
[CI] & "'") =0
     AND Dcount("1",
               "tab",
               "Importo=" & Str([Importo]) & " AND ci='" &
[CI] & "'") =2
cosa devo metterci al posto di "tab" dato che ho 2 tabelle correlate???


te l'ho copiata male perchè ho messo il from prima del where 
ma come faccio a mettere il nome della tabella se si tratta di una
query?
ci e importo appartengono a due tabelle diverse
ho provato a mettere il nome della query al posto di tab ma si IMPALLA
TUTTO
come faccio?


 cosa devo metterci al posto di "tab" dato che ho 2 tabelle correlate???
La funzione Dsum accetta solo una tabella.
Visto che Agenzie.ID è legato con Storico.ID io non metterei la tabella
Agenzie, e userei storico.ID  al posto di Agenzie.CI
-----------------
SELECT ID,
               Importo,
               Segno,
               ID_Part
FROM Storico
WHERE DSum("IIF(Segno='A',-1,1)*Importo",
              "Storico",
              "Importo=" & Str([Importo]) & " AND ID=" & [ID]) =0
--------------------
in questo caso do per scontato che ID sia un campo numerico intero.
Ciao Giorgio

CI sarebbe la procedura
come faccio a non usarlo se gli importi sono suddivisi per procedura?
importo    segno      CI(procedura)
500        D          SC
500        A          SC
500        A          SP
500        D          SP
ecc.


 ha scritto nel messaggio
news:71ac7329878d86215d7...@mygate.mailgate.org...

Nella FROM della tua Query
-----------------------
FROM Agenzie INNER JOIN Storico ON Agenzie.ID =
Storico.ID FROM
-----------------------
scrivi che la riga Agenzia in cui č presente il campo CI č legata allo
storico tramite ID.
Ora se esiste una sola procedura per Agenzia ovvero per un solo ID Agenzia
corrisponde un solo CI puoi usare ID al posto di CI.
Ciao Giorgio

ok posso anche risolvere mettendo CI anche nella tabella storico
ma aggiungendo ID alla fine=0
e facendo la select non mi restituisce NULLA


 e facendo la select non mi restituisce NULLA
non potresti postare il codice della query ?
In questo modo non capisco niente.
Ciao Giorigo

Allora questa è la query
SELECT Storico.ID, Storico.Importo, Storico.Segno, Agenzie.Dipendenza,
Agenzie.CI, Storico.ID_Part
FROM Agenzie INNER JOIN Storico ON Agenzie.ID = Storico.ID;
l'ID di storico è numerico ed è collegato con la tabella Agenzie
l'ID_Part e il contatore di storico
DIpendenza es.(6300,3500,2000,ecc.)e CI(SV,SC,PAS,ecc) fanno parte della
tabella
AGENZIE
mentre 
Importo,Segno, fanno parte della tabella STORICO
se proprio non è possibile usare il nome di due tabelle nel DSUM
potrei inserire Dipendenza e CI nella tabella STORICO..
che dici?
cmq sopra c'è la mia query.....!!!
dovrei adattarla a quello che mi hai mandato tu


 Importo,Segno, fanno parte della tabella STORICO
Visto che recuperi la riga dello storico tramite l'ID del''agenzia i campi
Dipendenza e CI non servono a niente !!!, servono solo a te per vederli
nella query.
Ciao Giorgio

quindi come devo fare la query?
con l'ID che mi hai scritto prima non mi restituiva niente!!!
ID=0


ho fatto cosi ma mi dice che ID può essere riferito a più tabelle
SELECT ID,Importo, Segno, ID_Part
FROM Agenzie INNER JOIN Storico ON Agenzie.ID =Storico.ID 
WHERE DSum("IIF(Segno='A',-1,1)*Importo", "Storico", "Importo=" &
Str([Importo]) & " AND Storico. ID=" & [Storico.ID]) =0


SELECT Storico.ID,Storico.Importo, Storico.Segno, ID_Part
FROM Agenzie  INNER JOIN Storico ON Agenzie.ID =Storico.ID 
WHERE DSum("IIF(Segno='A',-1,1)*Importo", "Storico", "Importo=" &
Str([Importo]) & " AND Storico.ID=" & [Storico.ID]) =0
ho fatto cosi ma non mi restituisce nessun CAMPO
niente



Ovviamente.
-------------------
 SELECT ID,Importo, Segno, ID_Part
 FROM Storico
 WHERE DSum("IIF(Segno='A',-1,1)*Importo", "Storico", "Importo=" &
Str([Importo]) & " AND ID=" & [ID]) =0
-------------------
Ciao Giorgio


veramente io ho suggerito questa e non vedo nessun ID=0
------------
SELECT ID,
               Importo,
               Segno,
               ID_Part
FROM Storico
WHERE DSum("IIF(Segno='A',-1,1)*Importo",
              "Storico",
              "Importo=" & Str([Importo]) & " AND ID=" & [ID]) =0
-----------------
comincio a pensare che sia una battaglia persa in partenza :(((
Ciao Giorgio

no non mi restituisce nulla!!!
SELECT ID,Importo, Segno, ID_Part
 FROM Storico
 WHERE DSum("IIF(Segno='A',-1,1)*Importo", "Storico", "Importo=" &
Str([Importo]) & " AND ID=" & [ID]) =0
non c'è nessun campo
l'ID della tabella storico è numerico l'ID della tabella Agenzie è un
Contatore
ma se ID è uguale a 0 come fa a restituirmi qualcosa???


aho ho copiato paro paro il tuo codice sql e l'ho inserito in access
sql e l'ho lanciato
NON RESTITUISCE nulla!!!!


hai ragione scusa mi sono distratto
lo 0 č riferito al DSUM
perň non mi restituisce nulla appena ho aggiunto l'ID perchč??
quale puň essere l'errore?



non sono il mago di OZ.
Vuoi mandarmi uno Zip del Database ?
te lo rimando con la query di selezioen e di eliminazione funzionanti.
togli "_No_Spalmer_" dal mio indirizzo.
Ciao Giorgio

potresti spiegarmi questa riga di codice che fa?
DSum("IIF(Segno='A',-1,1)*Importo", "Storico", "Importo=" &
Str([Importo]) & " AND ID=" & [ID]) =0;


adesso te lo mando
aspetta !!


giorgio te l'ho mandato!!


giorgio
rimandamelo allo stesso indirizzo da cui ti ho scritto


 Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG
Ricevuto,
certo che se il campo segno contiene 'C' e 'D' al posto di 'A' e 'D' come da
te specificato ai voglia a farlo funzionare.
prova cosě
---------------
SELECT ID,
               Importo,
               Segno,
               ID_Part
FROM Storico
WHERE DSum("IIF(Segno='D',1,-1)*Importo",
              "Storico",
              "Importo=" & Str([Importo]) & " AND ID=" & [ID]) =0
---------------
e per cancellare le righe
---------------
DELETE *
FROM Storico
WHERE DSum("IIF(Segno='D',1,-1)*Importo",
              "Storico",
              "Importo=" & Str([Importo]) & " AND ID=" & [ID]) =0
---------------
Ciao Giorgio

Che pirlaaaa
c'hai ragione....l'avevo tolto sulla prima query che mi avevi mandato
e l'ho dimenticato!!!



Dall'help di Access
-----------------
espressione.DSum(Espr, Dominio, Criteri)
espressione   Obbligatorio. Espressione che restituisce uno degli oggetti
indicati nell'elenco Si applica a.
Espr  Elemento String obbligatorio. Espressione che identifica il campo
numerico di cui si desidera calcolare il totale. È possibile che si tratti
di un'espressione stringa che identifica un campo di una tabella o di una
query oppure un'espressione che esegue un calcolo dei campi. In espr è
possibile includere il nome di un campo in una tabella, un controllo in una
maschera, una costante o una funzione. Se espr include una funzione, è
possibile che sia incorporata o definita dall'utente, ma non è possibile che
si tratti di un'altra funzione di aggregazione sui domini o di aggregazione
SQL.
Dominio  Elemento String obbligatorio. Un'espressione stringa che identifica
il set di record che costituisce il dominio. Può essere rappresentato dal
nome di una tabella o di una query.
Criteri  Elemento Variant facoltativo. Espressione stringa facoltativa
utilizzata per limitare l'intervallo di dati su cui viene eseguita la
funzione DSum. L'argomento criteri equivale spesso alla proposizione WHERE
priva della parola WHERE in un'espressione SQL. Se si omette l'argomento
criteri, la funzione DSum valuta espr sull'intero dominio. È necessario che
qualsiasi campo incluso in criteri sia incluso anche in dominio. In caso
contrario, la funzione DSum restituisce un valore Null.
----------------------
Ciao Giorgio

"grande GIorgio
funziona bene...faccio un pò di test
allora dato che sei un grande in SQL, da quanto ho capito
ti pongo un quesito un pò più difficilotto:
potrei io sempre in sql fare una select aggiungendola a quella che già
mi hai
fatto tu che oltre a eliminare gli importi uguali Dare e avere 
toglie anche gli importi che si incrociano??
esempio:
Importi   Segno  procedura
100         D    SV
50          A    SV
50          A    SV
cioè in pratica dovrei far incrociare tutti quegli importi che possono
portare
saldo a 0
è POSSIBILE una cosa del genere????



Ciao,
con il solo linguaggio SQL di Access è molto dura, non prevede l'utilizzo di
stored procedure, l'unica cosa che mi viene in mente è quella di creare un
recordset in VB contenente il progressivo di ogni Agenzia, quando incontri
il Progressivo=0 procede alla cancellazione verso l'alto.
ID_Part Importi   Segno  procedura  Progressivo
-----------------
1     100         D    SV      100
10    50          A    SV        50
21    50          A    SV         0   <--- Cancellare da qui in su
85   250         D    SV       250
----------------
Questo a grandi linee poi tra il dire e il fare .....
:-)
Ciao Giorgio
****
ps ho notato che utilizzi il tipo di dato Doppia Precisione per memorizzare
gli importi, essendo di natura impreciso potresti incontrare problemi nella
query precedente ovvero puoi ritrovarti al posto del risultato 0
un'approssimazione a 0 come -0.0000000000000000001 quindi <> da 0
a scanso di equivoci usa la funzione Round
------------------------
DELETE *
FROM Storico
WHERE Round(DSum("IIF(Segno='D',1,-1)*Importo",
              "Storico",
              "Importo=" & Str([Importo]) & " AND ID=" & [ID]),2) =0
-------------------------
Ciao Giorgio

Misà che è un pò complicato....
grazie di nuovo Giorgio
posso scriverti nel caso in cui mi trovassi in difficoltà in futuro in
SQL
o ti scoccia???



il luogo migliore per incontrarci è proprio l'NG, in genere frequento (per
Access) microsoft.public.it.office.access poi ogni tanto faccio una scappata
qui e su it.comp.appl.access, sia l' NG di Microsoft che quello di
it.comp.appl.access sono riserveti ad Access quindi troverai molte persone
che potranno offrirti il loro valido aiuto. :-)
Ciao Giorgio

Ok 
quello della microsoft non l'ho mai frequentato
comincerò a farlo
Giorgio grazie mille



per completezza devo precisare una cosa, la query è in sola lettura se
l'aggregazione è presente nella SELECT o nella FROM
Se l'aggregazione è presente solo nella WHERE  è possibile cancellare i
record.
Così cancella i record
---------------
DELETE *
FROM Storico
WHERE (SELECT SUM(IIF(Segno='D',1,-1)*Importo) AS Saldo
              FROM Storico AS St2
             Where St2.Importo=Storico.Importo
                 AND St2.ID=Storico.ID)=0
-----------------
Così no
-----------
DELETE St1.*
FROM   Storico St1
   INNER JOIN
       (Select Importo,ID
        From Storico
        GROUP BY Importo,ID
        HAVING SUM(Iif(Segno= 'D',1,-1)* Importo)=0
        ) AS St2
   ON St1.Importo=St2.Importo AND St1.ID=St2.ID
-----------
Ciao Giorgio