webForumDet fria alternativet

Join som returnerar "för många poster"

11 svar · 378 visningar · startad av @nders

@ndersMedlem sedan juni 200032 969 inlägg
#1

Hepp!

Jag sitter och sliter med en join som returnerar för många poster. Eller rättare sagt, den returnerar korrekt, och det är det jag skulle vilja förhindra. :)

Så här ser joinen ut:

    LEFT JOIN SRONFP AS P1 ON (P1.NFNANO = CUSTOMER.KUNDNR AND P1.NFDFFX='Y' AND P1.NFPHTP LIKE '*PHONE%')

Det jag måste se till är att joinen aldrig returnerar mer än en post, och där går jag bet.

Edit: Det spelar ingen som helst roll vilken post som returneras, under förutsättning att det inte kommer mer än en.

Edit2: Vi använder SQL Server 2000.

Någon med kloka idéer?

Mvh och tfp,

PDahlenMedlem sedan apr. 2004778 inlägg
#2

1. Är du säker på att det inte finns flera poster som de givna värdena passar in på?

2. Hur ser hela sql-satsen ut

3. Hur ser ditt resultat ut

@ndersMedlem sedan juni 200032 969 inlägg
#3
  1. Det finns (i stort sett alltid) ingen eller en post som matchar joinvillkoret, men i bland händer något konstigt med replikeringen, och då kan det hända att det kommer två poster i tabellen.

  2. Det spelar egentligen ingen roll. Den är stor som en medelstor österrikisk alp, men jag har förkortat den en himla massa här, så den blir läsbar.

SELECT DISTINCT 'Y' AS ACTIVE, 
     CASE WHEN CUSTOMER.KAMPANJPRIS = 1 THEN 'Y' ELSE 'N' END AS CAMPAIGN_PRICE , CUSTOMER.PRISLISTA, 
     CUSTOMER.KUNDNR as CUST_ID, P1.NFPHNO AS PHONE, P2.NFPHNO AS FAX
     FROM PRODD..CUSTOMER CUSTOMER 
     LEFT JOIN SRONFP AS P1 ON (P1.NFNANO = CUSTOMER.KUNDNR AND P1.NFDFFX='Y' AND P1.NFPHTP LIKE '*PHONE%')
     LEFT JOIN SRONFP AS P2 ON (P2.NFNANO = CUSTOMER.KUNDNR AND P2.NFDFFX='Y' AND P2.NFPHTP LIKE '*FAX%')
WHERE CUSTOMER.kundnr = '52213'
  1. Eftersom det finns två poster för telefonnummer i grunddatat får jag två poster.
Active   CAMPAIGN_PRICE    PRISLISTA   CUST_ID   PHONE           FAX
Y        Y                 2           52213     55555555        66666666
Y        Y                 2           52213     77777777        66666666

Jag vill alltså ha en post.

JonMedlem sedan juli 20011 304 inlägg
#4

Vet inte om jag är lite morgontrött men varför inte slänga in en Top 1 ?

PDahlenMedlem sedan apr. 2004778 inlägg
#5

Eftersom du har två JOINs och i den ena frågar efter Phone och den andra Fax så får du två svar.
Det första resultatet får du för att i P1 så är telefonnumret rätt.
Det andra resultatet får du för att du har din andra join, P2, och där stämmer numret också men då är det faxnummer.
Om jag tolkar rätt så ser tabellerna ut så här:

 CUSTOMER
    52213    2     Y      Y

 SRONFP
    52213    7777777777
    52213     555555555

Där det ena numret är telefon och det andra fax.
Däremot så borde ditt resultat ha samma Phone och Fax i båda posterna eftersom det är samma kund som hämtas två gånger. Stämmer det?
För i så fall borde det räcka med att du lägger till en GROUP BY och har med samtliga kolumnnamn som du har i resultatet.

@ndersMedlem sedan juni 200032 969 inlägg
#6

Egentligen är det en join med c:a 10 tabeller, och det är mina två outer joins som inte får göra så det blir två poster per kundnummer. WHERE-satsen finns inte där egentligen, utan ger ett totalt utdrag ur vårt kundregister. En post per kundnummer i resulterande recordset är det jag behöver alltså.

@ndersMedlem sedan juni 200032 969 inlägg
#7

Eftersom du har två JOINs och i den ena frågar efter Phone och den andra Fax så får du två svar.
Det första resultatet får du för att i P1 så är telefonnumret rätt.
Det andra resultatet får du för att du har din andra join, P2, och där stämmer numret också men då är det faxnummer.

Nej, telefonnummer och faxnummer kommer i samma post. Kunden i exempelutdraget ovan har ett faxnummer, och två telefonnummer. Eftersom kunden har två telefonnummer genererar joinen två poster. Joinerna levererar alltså helt rätt resultat, men det är det jag inte vill. Jag vill kasta bort godtycklig post om det i recordsetet som skapas finns mer än en post på något kundnummer.

Däremot så borde ditt resultat ha samma Phone och Fax i båda posterna eftersom det är samma kund som hämtas två gånger. Stämmer det?

Njae. Två telefonnummer och ett faxnummer.

Mvh

LarsGMedlem sedan dec. 200012 464 inlägg
#8
SELECT  'Y' AS ACTIVE, 
     CASE WHEN CUSTOMER.KAMPANJPRIS = 1 THEN 'Y' ELSE 'N' END AS CAMPAIGN_PRICE , CUSTOMER.PRISLISTA, 
     CUSTOMER.KUNDNR as CUST_ID, max(P1.NFPHNO) AS PHONE, P2.NFPHNO AS FAX
     FROM PRODD..CUSTOMER CUSTOMER 
     LEFT JOIN SRONFP AS P1 ON (P1.NFNANO = CUSTOMER.KUNDNR AND P1.NFDFFX='Y' AND P1.NFPHTP LIKE '*PHONE%')
     LEFT JOIN SRONFP AS P2 ON (P2.NFNANO = CUSTOMER.KUNDNR AND P2.NFDFFX='Y' AND P2.NFPHTP LIKE '*FAX%')
WHERE CUSTOMER.kundnr = '52213'
group by
         CUSTOMER.PRISLISTA, 
         CUSTOMER.KUNDNR , 
         P2.NFPHNO
@ndersMedlem sedan juni 200032 969 inlägg
#9

Tack!

Kan jag göra motsvarande för att bara få de två joinerna i exemplet att inte returnera mer än en post tillsammans? Jag skulle *helst* undvika att lägga en group by där, eftersom hela frågan är en join mellan en herrans massa tabeller, och det hämtas en hel massa fält i frågan? Eller är GROUP BY i det här fallet det enda / bästa sättet?

Mvh

@ndersMedlem sedan juni 200032 969 inlägg
#10

Äsch, det verkar inte bli så kladdigt. Den tar vi. :)

Tack för hjälpen!

Mvh

LarsGMedlem sedan dec. 200012 464 inlägg
#11

Ett alternativ är att använda en deriverad tabell

select a,b,c
from t1 left join (select fk,b,max(c) as c from t2
where ... 
group by b,fk) dt on t1.pk = dt.fk
@ndersMedlem sedan juni 200032 969 inlägg
#12

Hmm, ok :)

Tack!

Mvh
anders

137 ms totalt · 3 externa anrop · v20260731065814-full.fb544a5a
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
134 ms — hämta tråd, inlägg och bilagor (db)