[MSSQL] Soort intersect

Pagina: 1
Acties:

  • _js_
  • Registratie: Oktober 2002
  • Laatst online: 13-01 07:19
Ik lever diensten.
Ik houd bij wanneer een dienst wordt geleverd.
Diensten kunnen vooraf in bulk worden ingekocht.

Ik wil voor elke geleverde dienst zien of die is ingekocht, en zo ja, wat het id nummer is van de inkoop.

Vereenvoudigd datamodel:

tblIngekochteDiensten
code:
1
2
3
4
5
IDid | dienst | aantal
-----+--------+-------
1    | a      | 2
2    | a      | 2
3    | b      | 3


tblGeleverdeDiensten
code:
1
2
3
4
5
6
7
8
9
10
GDid | dienst
-----+-------
1    | a
2    | a
3    | a
4    | a
5    | a
6    | b
7    | b
8    | c


Gewenst resultaat:
code:
1
2
3
4
5
6
7
8
9
10
GDid | dienst | IDid
-----+--------+-----
1    | a      | 1
2    | a      | 1
3    | a      | 2
4    | a      | 2
5    | a      | NULL
6    | b      | 3
7    | b      | 3
8    | c      | NULL


Ik heb geprobeerd het met een join te doen, maar ik kon niet genoeg join voorwaarden bedenken, ik heb het geprobeerd met een extra tel-tabel, om de ingekochte diensten tabel om te zetten naar een rij, en dan een join of een intersect, maar ook dat lukte niet zoals ik het wil.

De geleverde diensten tabel wordt gevuld door een applicatie die niet gewijzigd kan worden. Wel kan ik eventueel triggers maken om andere tabellen te vullen aan de hand van wijzigingen in die tabel.

Heeft iemand een idee hoe ik het gewenste resultaat kan bereiken met een query, of eventueel extra tabellen, triggers, etc.?

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:03
wil jij niet gewoon een outer join ?
Verder snap ik niet hoe je aan
1 a 1
en
3 a 2
komt
:?

[ Voor 47% gewijzigd door whoami op 20-10-2005 16:52 ]

https://fgheysels.github.io/


  • Dido
  • Registratie: Maart 2002
  • Laatst online: 16:35

Dido

heforshe

Dit gaat nog vies tegenvallen: hoe bepaal je dat GDid 1 bij IDid 1 hoort, maar GDid 3 bij IDid 2?
De enige "link" die je hebt is dat beiden dienst "a" hebben, maar welke moet je hebben?

Dat zul je, ben ik bang, applicatief op moeten lossen, omdat je bij moet houden hoeveel "voorraad" je nog hebt.

Wat betekent mijn avatar?


  • P_de_B
  • Registratie: Juli 2003
  • Niet online
whoami schreef op donderdag 20 oktober 2005 @ 16:51:
wil jij niet gewoon een outer join ?
Verder snap ik niet hoe je aan
1 a 1
en
3 a 2
komt
:?
Volgens mij is het zo: Dienst 'a' is gewoon 4 keer ingekocht, en 5 keer geleverd. De geleverde diensten moeten volgens mij afgeboekt worden van de oudste ingekochte dienst voorraad. Omdat er 4 keer dienst 'a' is gekocht, is de 5e geleverde dienst NULL bij IDid.

Heb ik dit goed begrepen?

Oops! Google Chrome could not find www.rijks%20museum.nl


  • _js_
  • Registratie: Oktober 2002
  • Laatst online: 13-01 07:19
Dido: Ja, ik vond het zelf ook al vies tegenvallen ;)

Wat ik al wel als idee heb geprobeerd is dynamisch een lange query bouwen, maar die query wordt wel heel snel heel erg groot, en neemt ook nog wel wat tijd om uit te voeren, dan werd het als volgt:
voor elke rij in de IngekochteDiensten tabel maak ik de query iets langer:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
SELECT TOP [i]aantal van rij1 de tabel[/i] * 
FROM tblGeleverdeDiensten 
WHERE dienst = [i]dienst van rij1 uit de tabel[/i]

UNION

SELECT TOP [i]aantal van rij2 de tabel[/i] * 
FROM tblGeleverdeDiensten 
WHERE dienst = [i]dienst van rij2 uit de tabel[/i]
 AND GDid NOT IN (
  SELECT TOP [i]aantal van rij1 de tabel[/i] * 
  FROM tblGeleverdeDiensten 
  WHERE dienst = [i]dienst van rij1 uit de tabel[/i]
 )


P_de_B: ja, dat klopt.

  • JapJap
  • Registratie: Maart 2001
  • Laatst online: 07-01 11:02
Dit werkt voor je voorbeeld:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
select
   b1.*,
   (select min(IDid) 
    from tblIngekochteDiensten a1 
    where a1.dienst = b1.dienst and exists (
         select top 1 1
         from tblIngekochteDiensten a2 
         where a2.dienst = a1.dienst 
           and a2.dienst = b1.dienst 
           and a2.IDid <= a1.IDid 
         having sum(aantal) >= 
           (select count(1) 
            from tblGeleverdeDiensten b2 
            where b2.dienst = b1.dienst 
              and b2.GDid  <= b1.GDid)
         )
   )
from tblGeleverdeDiensten b1

[ Voor 7% gewijzigd door JapJap op 20-10-2005 18:02 . Reden: Opmaak ]


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Is het niet handiger om een kopel tabel te maken waarin staat uit welk inkoop record een geleverd record is geleverd?

Dan moet het daarna ook wel mogenlijk zijn om een select te doen waarbij je de oudste inkoop selecteerd waarvan nog niet alles is uitgeleverd.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”

Pagina: 1