Archief - Subquery op meerdere kolommen

Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.

Radiance

Legacy Member
Hi allemaal,

Ik probeer een query te maken op SQL 2005 waar ik in essentie een subquery zou moeten kunne draaien op 2 kolommen, wat blijkbaar niet kan in SQL Server.

Even de situatie schetsen, in sterk vereenvoudige vorm ziet mijn tabel er zo uit :
Code:
CREATE TABLE [dbo].[Termination_Call_Detail](
	[RouterCallKeyDay] [dbo].[DBINT] NULL,
	[RouterCallKey] [dbo].[DBINT] NULL,
	[RouterCallKeySequenceNumber] [dbo].[DBINT] NULL
	[ANI] [varchar](32) NULL,
	[DNIS] [varchar](32) NULL

Voorbeeld van de inhoud zou kunnen zijn :
Code:
VALUES (1,1, 1, '2000', '3000')
VALUES (1,1, 2, '2000', '')
VALUES (1,1, 3, '2000', '5000')
VALUES (1,2, 1, '2200', '3000')
VALUES (3,1, 1, '2300', '4000')
VALUES (3,1, 2, '2300', '')

Misschien helpt het als ik er een beetje context aan geef, het gaat om een tabel met telefoongesprekken. Rijen waar zowel RouterCallKeyDay en RouterCallKey dezelfde zijn, zijn aan elkaar gerelateerd. Nu wil ik alle gerelateerde rijen ophalen als een van de call legs (gesprekken) aan mijn WHERE clause voldoet.

Voorbeeld van de query die ik in gedachten had.
Code:
SELECT Termination_Call_Detail.*
FROM Termination_Call_Detail
WHERE
 (RouterCallKeyDay, RouterCallKey) IN
  (
   SELECT RouterCallKeyDay, RouterCallKey
   FROM Termination_Call_Detail
   WHERE DNIS = '5000'
  )

Het idee van de bovenstaande query is dus dat ie de eerste 3 records ophaalt omdat in de 3e de DNIS 5000 is en de eerste 3 records dezelfde RouterCallKeyDay + RouterCallKey hebben. Maar dat kan blijkbaar niet in SQL Server (krijg een syntax fout op de komma in de WHERE clause).

Heeft iemand enige suggesties hoe ik dit kan oplossen ?
Je kon het waarschijnlijk al raden, maar ik kan het schema niet aanpassen en ik kan eigenlijk enkel met een SELECT werken.

Laat het gerust weten als ik de situatie verder kan verduidelijken.

adrianhates

Legacy Member
2 subqueries gebruiken? Ik dacht dat het onmogelijk was om in een subquery een result set terug te geven van meer dan 1 kolom als ge die resultset gaat vergelijken met een kolom in uw upperquery. Het wordt anders moeilijk om de waarde de matche met het result van de subquery..

Ik heb zoiets nog nooit gezien eig en dacht ook dat het niet mogelijk was ( in MySQL alleszins )

SELECT Termination_Call_Detail.*
FROM Termination_Call_Detail
WHERE
(RouterCallKeyDay, RouterCallKey) IN

(
SELECT RouterCallKeyDay, RouterCallKey
FROM Termination_Call_Detail
WHERE DNIS = '5000'
)

Edit:

Doet dit niet hetzelfde?

Code:
SELECT RouterCallKeyDay, RouterCallKey
FROM Termination_Call_Detail
WHERE DNIS = '5000'

Anders moet ge uw bedoeling nog maar wat beter verduidelijken.. :)

kows

Legacy Member
DECLARE @Temp TABLE(
RouterCallKeyDay int,
RouterCallKey int
)

insert into @Temp(RouterCallKeyDay,RouterCallKey)
SELECT RouterCallKeyDay, RouterCallKey
FROM Termination_Call_Detail
WHERE DNIS = '5000'

select * from Termination_Call_Detail tcd
INNER JOIN @Temp t on tcd.RouterCallKey = t.RouterCallKey
AND tcd.RouterCallKeyDay = t.RouterCallKeyDay

dit denk ik zo als ik het goed snap.
adhv DNIS haal je een routercallkeyday & routercallkey op,
en deze combo komt 3x voor in dezelfde tabel?

dJeez

Legacy Member
Da's toch oplosbaar met een eenvoudige self-join of zie ik iets over het hoofd?

Iets als volgt dus :
SELECT tcd1.*
FROM Termination_Call_Detail AS tcd1,
Termination_Call_Detail AS tcd2
WHERE tcd1.RouterCallKeyDay=tcd2.RouterCallKeyDay and tcd1.RouterCallKey=tcd2.RouterCallKey AND tcd2.DNIS='5000'

Zeg anders eens wat het resultaat zou moeten zijn bij DNIS=3000 in uw voorbeeld :p.

kows

Legacy Member
hoe ik het zie:
tabel:
RCKD RCK DNIS
321 654 100
123 456 200
123 456 300
123 456 400

en zijn select op DNIS = 400 zou dus de laatste drie rijen moeten weergeven.
Met een join zou je enkel laatste rij hebben denkik, alhoewel...

Radiance

Legacy Member
kows zei:
...
dit denk ik zo als ik het goed snap.
adhv DNIS haal je een routercallkeyday & routercallkey op,
en deze combo komt 3x voor in dezelfde tabel?
Yup, dit zou zeker doen wat ik wil, maar ik kan geen schema changes doen, ook niet tijdelijk.

dJeez zei:
Da's toch oplosbaar met een eenvoudige self-join of zie ik iets over het hoofd?
Ik had om een of andere reden besloten dat dat niet kon, maar misschien moet ik het nog eens terug evalueren, want ik zie zelf al niet meer waarom ik dat uitgesloten heb :)
Zeg anders eens wat het resultaat zou moeten zijn bij DNIS=3000 in uw voorbeeld :p.
Code:
VALUES (1,1, 1, '2000', '3000')
VALUES (1,1, 2, '2000', '')
VALUES (1,1, 3, '2000', '5000')
VALUES (1,2, 1, '2200', '3000')

Voorlopig had ik volgende oplossing gevonden, maar je moet geen SQL genie zijn om te begrijpen dat dit qua performance een volledige killer is :)
Code:
WHERE
  rcd.RouterCallKeyDay + '-' + rcd.RouterCallKey IN
   (
    SELECT DISTINCT RouterCallKeyDay + '-' + RouterCallKey 
    FROM Route_Call_Detail
    WHERE ...

Moto

Legacy Member
Gewoon zo doen

Code:
DECLARE @Tmp as int

select @Tmp = 4000

SELECT Termination_Call_Detail.* 
FROM Termination_Call_Detail,
(SELECT RouterCallKeyDay, RouterCallKey 
 FROM Termination_Call_Detail where DNIS = @Tmp
) AS TmpTbl
WHERE 
Termination_Call_Detail.RouterCallKeyDay = TmpTbl.RouterCallKeyDay AND
Termination_Call_Detail.RouterCallKey    = TmpTbl.RouterCallKey

dJeez

Legacy Member
Moto zei:
Gewoon zo doen

Code:
DECLARE @Tmp as int

select @Tmp = 4000

SELECT Termination_Call_Detail.* 
FROM Termination_Call_Detail,
(SELECT RouterCallKeyDay, RouterCallKey 
 FROM Termination_Call_Detail where DNIS = @Tmp
) AS TmpTbl
WHERE 
Termination_Call_Detail.RouterCallKeyDay = TmpTbl.RouterCallKeyDay AND
Termination_Call_Detail.RouterCallKey    = TmpTbl.RouterCallKey
Dat is eigenlijk net dezelfde query als diegene die ik eerder poste, maar in iets andere vorm. Hij zal echter vermoedelijk trager zijn aangezien je met een subquery werkt, tegenover de self-join in mijn geval (hangt een beetje af van optimalisaties van SQL server).

@Radiance: Geeft de query die ik heb gepost niet gewoon de resultaten die je verwacht?

Moto

Legacy Member
Hij zal echter vermoedelijk trager zijn aangezien je met een subquery werkt
Euhm... nee.
Anyway discussieren hierover is zinloos, enigste dat telt is effectief testen met grote hoeveelheden data, en daar heb ik geen tijd/goesting voor.
Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.
Terug
Bovenaan