SQL udvidet "NOT IN" query

Tags:    sql

<< < 123 > >>
Jeg har en opgave hvor jeg har 2 tabeller hvori der er en masse rækker som sagtens kan være dubletter.

opgaven går på dette.:

jeg har fx. 5 linjer fra table1

10001
10002
10001
10004
10005

som det ses er der i denne 1 dublet "10001" men denne skal behandles som værende unik...

i table 2 har jeg:

10001
10002
10004
10005

et resultat af en "NOT IN" kørsel vil i dette scenarie være tomt. men jeg har brug for at den viser at der rent faktisk er 1 række fra table1 som ikke er i table2 (10001)

værdien er der i table2, men den er allerede brugt 1 gang på den første "10001"

jeg gætter på at jeg på en eller anden måde skal lave en query hvor den kun bruger 1 række en gang og så går videre kronologisk...

jeg ved ikke om det overhovedet giver mening som jeg har forklaret det, ellers må i lige skrive...





22 svar postet i denne tråd vises herunder
5 indlæg har modtaget i alt 1 karma
Sorter efter stemmer Sorter efter dato
Er der tale om en MSSQL eller en mysql?

Er der tale om en MSSQL server, så kan du prøve at bruge EXCEPT

SELECT * FROM tabel
EXCEPT
SELECT * FROM tabel2

De skal kunne union'es. Jeg er ikke sikker på om det er det du skal bruge, men giv lige besked igen. Måtte lige slå op i min database bog :)



Hvordan kan forslaget om en alternativ løsning være overflødig ?
At gøre nogen opmærksom på at man måske kigger i en forkert retning ?
Det er sådan man når frem til den rigtige istedet for en uoptimal løsning.

Jeg ved ikke med dig Brian, men hvis jeg stiller et spørgsmål herinde, og nogen opfordrer mig til at gøre noget andet end jeg selv lægger op til, så tager jeg med glæde imod alternative forslag.



@Robert - jeg ville være helt enig, men der er to ting der er i vejen med din fremgangsmåde:

1. Du siger stort set bare "You're doing it wrong" - hvad ville være bedre?
2. Lad os nu antage at Dion ikke er i en position til at ændre database strukturen, hvad så?



1) Vi skal vide mere om, hvilke data han arbejder med og hvordan de hænger sammen.
2) Så siger han det nok, og så er der ingen skade sket.



Hvad med at afbryde diskussionen, tage den pr. PM og så nøjes med at give de svar trådstarter ønskede svar på. :)
Det andet her er på vej til at køre op i en spids. Det er der ingen grund til.



Jeg kan ikke ændre dataene ej heller strukturen da det er regnskabs og bogføringsdata som skal være 100% som kilden..

det handler om afstemning hvor et beløb i banken skal tjekkes om det er i bogføringssystemet, hvis ikke skal det generere et resultat på den linje ;-)

for et real life eksempel så kan det være man i banken har modtaget
2x250kr

men i regnskabssystemet findes der kun 1x250kr som er blevet bogført, ved normal sammenligning vil den jo sige at posten er der fordi 250kr eksisterer...



det er MySQL jeg benytter...

jeg prøver at forske lidt nærmere i cursor for at lave kronologisk sammenligning.





tabellerne indholder følgende:

tabel1:
bogfort maaned tekst rentedato belob
2011-04-28 4 Dankort-salg 27.04 -------- xx33 2011-04-28 264,0

bogfort = indeholder dato (kan ikke matches da den altid er forskudt)
maaned = indeholder måned (4 = april)
tekst = indeholder teksten som er i bank/regnskab, kan ikke matches
rentedato = indeholder rentedato (kan ikke bruges til noget)
belob = indeholder beløbet som altid skal være 100% identisk med tabel2

tabel2:
bogfort maaned tekst rentedato belob
2011-04-29 4 80335 Indbet. fak. 53633 264,00
2011-04-10 4 79422 Indbet. fak. 52590 264,00

kun man evt. tilføje et indeks til hver af tabellerne og bruge det som pointer ?

så den løber tabel1 igennem med tabel2 kronologisk og så laver en update på at belobbrugt = 1 og hvis belobbrugt = 1 skipper den i næste samligning...?





Jeg tror du skal ud i noget i denne stil:

Fold kodeboks ind/udKode 


Table_1: Indeholder posteringer fra banken
Table_2: Indeholder posteringer fra bogføring

Edit:
Tror faktisk den godt kan give lidt problemer hvis der ikke er nogen "keys" man kan lave den på. Jeg vil dog lige vente med at høre hvad du siger.



Indlæg senest redigeret d. 15.10.2011 12:25 af Bruger #6559
Jeg tror du skal ud i noget i denne stil:

Fold kodeboks ind/udKode 


Table_1: Indeholder posteringer fra banken
Table_2: Indeholder posteringer fra bogføring

Edit:
Tror faktisk den godt kan give lidt problemer hvis der ikke er nogen "keys" man kan lave den på. Jeg vil dog lige vente med at høre hvad du siger.


ovenstående query kan desværre ikke bruges da den som tidligere nævnt finder 250 = 250 (selvom 250 er brugt mere end én gang)

jeg har nu løbet hele skidtet igennem manuelt for at vide resultat jeg skal nå frem til i antal rækker der ikke eksisterer.:

banken skal give 138 rækker som ikke findes i regnskabstabellen..

jeg har forsøgt med din query, denne giver 93 resultater...

umiddelbart tror jeg måske at det er nemmere at finde løsning i et foreach loop i php... så køre den jo arrayet igennem kronologisk... hvis jeg så benytter ordering på begge tabeller, så burde det vel egentlig være muligt... og så vedhjælp af en "if" sammenligning kan jeg smide rækker der ikke eksistere ud i et særskilt array...

nogen tanker om dette?





@Dion - sådan som jeg ser det er udfordringen sådanset at få performance til at være acceptabel. Du kan helt sikkert gøre det hele i PHP, det er der intet problem i - og hvis udførselstiden er fin via den måde (samt hukommelsesforbrug osv) - og du ved at det ikke skal skalere op til større mængder data end det du tester på - så gør det da endelig på den måde.

Omvendt set, hvis ikke det virker, så gælder det altså om at få konstrueret en query sammen som kan ramme nogle indexes på den rigtige måde.

Du har tidligere sagt at du ikke kan ændre i databaseskemaet - men bare for at være sikker - du har ikke mulighed for at smide nogle primær/fremmednøgler ned i de tabeller? Og ellers, har du prøvet det forslag jeg kom med, og i så fald, hvad var udfaldet ved det?



<< < 123 > >>
t