/ Forside / Teknologi / Udvikling / SQL / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
SQL
#NavnPoint
pmbruun 1704
niller 962
fehaar 730
Interkril.. 701
ellebye 510
pawel 510
rpje 405
pete 350
gibson 320
10  smorch 260
MySQL - Conditional join
Fra : Jens Thomsen


Dato : 21-04-08 04:29

Jeg har tre tabeller:
emails
email_out_attr
email_in_attr

I emails har jeg basis information om emailen, e.g. tekst.
I email_out_attr har jeg den info der er specifik for udgående emails, e.g.
afsender og i email_in_attr har jeg tilsvarende modtager og tidspunkt for
modtagelse mm.

I emails har jeg en kolonne "direction" som kan antage IN eller OUT.

Jeg vil gerne JOINe den rigtige tabel på baseret på om det er en indgående
eller udgående email.

Kan man det i MySQL 5+?

Bemærk: Eksemplet er eksemplificeret - det er at betragte som et teoretisk
spørgsmål



 
 
Kristian Damm Jensen (21-04-2008)
Kommentar
Fra : Kristian Damm Jensen


Dato : 21-04-08 14:57

Jens Thomsen wrote:
> Jeg har tre tabeller:
> emails
> email_out_attr
> email_in_attr
>
> I emails har jeg basis information om emailen, e.g. tekst.
> I email_out_attr har jeg den info der er specifik for udgående
> emails, e.g. afsender og i email_in_attr har jeg tilsvarende modtager
> og tidspunkt for modtagelse mm.
>
> I emails har jeg en kolonne "direction" som kan antage IN eller OUT.
>
> Jeg vil gerne JOINe den rigtige tabel på baseret på om det er en
> indgående eller udgående email.
>
> Kan man det i MySQL 5+?

Nej, men du kan joine begge tabeller på med et outer join, og derefter
frasortere den ikke brugte information.

select *
from emails e
outer join email_out_attr out on e.id = out.id
outer join email_in_attr in on e.id = in.id


--
Venlig hilsen /Best regards
Kristian Damm Jensen



Jens Thomsen (22-04-2008)
Kommentar
Fra : Jens Thomsen


Dato : 22-04-08 04:40

> Nej, men du kan joine begge tabeller på med et outer join, og derefter
> frasortere den ikke brugte information.
>
> select *
> from emails e
> outer join email_out_attr out on e.id = out.id
> outer join email_in_attr in on e.id = in.id


Hmm, de to tabeller har enkelte sammenfaldende kolonnenavne, og så skal jeg
i koden vide, hvilken der skal plukkes fra alligevel.
Havde ellers været smart

Man kan heller ikke med views?

Er en outer join det samme som en left join?



Kristian Damm Jensen (22-04-2008)
Kommentar
Fra : Kristian Damm Jensen


Dato : 22-04-08 06:45

Jens Thomsen wrote:
>> Nej, men du kan joine begge tabeller på med et outer join, og
>> derefter frasortere den ikke brugte information.
>>
>> select *
>> from emails e
>> outer join email_out_attr out on e.id = out.id
>> outer join email_in_attr in on e.id = in.id
>
>
> Hmm, de to tabeller har enkelte sammenfaldende kolonnenavne, og så
> skal jeg i koden vide, hvilken de skal plukkes fra alligevel.

Ja. Du slipper ikke for at skelne i koden, på en eller anden måde.,

En anden idé er at bruge en union:

select <attribut-liste>
from emails e
join email_out_attr out on e.id = out.id
union
select <attribut-liste>
from emails e
join email_in_attr in on e.id = in.id

Det forudsætter bare at du sikrer at <attribut-liste> er ens for de to
selects, hvilket formodentlig vil gøre det nødvendigt at indføre
pseudo-kollonner i select, fx sådan her:

select e.id, out.adresse, NULL as navn
from emails e
join email_out_attr out on e.id = out.id
union
select e.id, NULL as adresse, in.navn
from emails e
join email_in_attr in on e.id = in.id

> Havde ellers været smart
>
> Man kan heller ikke med views?

Et view er i princippet ikke andet end en præfabriket select. Hvor du kan
skrive et view, kan du også skrive "(select ....) as view_select". Det
løser ikke noget.

> Er en outer join det samme som en left join?

Min fejl. Der skulle have stået "left join" eller "left outer join". "outer
join" giver ikke mening i sig selv.

--
Venlig hilsen /Best regards
Kristian Damm Jensen



Peter Brodersen (22-04-2008)
Kommentar
Fra : Peter Brodersen


Dato : 22-04-08 13:48

On Tue, 22 Apr 2008 07:44:35 +0200, "Kristian Damm Jensen"
<dNOamSPm.uAMsenet@kristiandamm.dk> wrote:

>select e.id, out.adresse, NULL as navn
>from emails e
>join email_out_attr out on e.id = out.id
>union
>select e.id, NULL as adresse, in.navn
>from emails e
>join email_in_attr in on e.id = in.id

Man kan i udtrækket også tilføje et felt, som indikerer, hvor den række
kommer fra - som man så kan begrænse sit udtræk på, fx:

SELECT ...., 'tabel1' AS tabelnavn
....
SELECT ...., 'tabel2' AS tabelnavn
....
WHERE tabelnavn = IF(foo = bar, 'tabel1', 'tabel2)

Den mulighed eksisterer både med at joine begge tabeller og ved en union.

--
- Peter Brodersen
Kendt fra Internet

Kristian Damm Jensen (22-04-2008)
Kommentar
Fra : Kristian Damm Jensen


Dato : 22-04-08 14:02

Peter Brodersen wrote:
> On Tue, 22 Apr 2008 07:44:35 +0200, "Kristian Damm Jensen"
> <dNOamSPm.uAMsenet@kristiandamm.dk> wrote:
>
>> select e.id, out.adresse, NULL as navn
>> from emails e
>> join email_out_attr out on e.id = out.id
>> union
>> select e.id, NULL as adresse, in.navn
>> from emails e
>> join email_in_attr in on e.id = in.id
>
> Man kan i udtrækket også tilføje et felt, som indikerer, hvor den
> række kommer fra - som man så kan begrænse sit udtræk på, fx:
>
> SELECT ...., 'tabel1' AS tabelnavn
> ...
> SELECT ...., 'tabel2' AS tabelnavn
> ...
> WHERE tabelnavn = IF(foo = bar, 'tabel1', 'tabel2)
>
> Den mulighed eksisterer både med at joine begge tabeller og ved en
> union.

Så bliver du da vist nødt til at have en parentes om:
(SELECT ...., 'tabel1' AS tabelnavn
....
UNION
SELECT ...., 'tabel2' AS tabelnavn
....
)
WHERE tabelnavn = IF(foo = bar, 'tabel1', 'tabel2)

for at sikre at where-klausulen dækker begge selects. Og så melder
spørgsmålet sig: Kan man have en union i en sub-select? (Ellers kan man
naturligvis sætte klausulen på begge selects.)

--
Venlig hilsen /Best regards
Kristian Damm Jensen



Peter Brodersen (22-04-2008)
Kommentar
Fra : Peter Brodersen


Dato : 22-04-08 21:39

On Tue, 22 Apr 2008 15:01:59 +0200, "Kristian Damm Jensen"
<dNOamSPm.uAMsenet@kristiandamm.dk> wrote:

>for at sikre at where-klausulen dækker begge selects. Og så melder
>spørgsmålet sig: Kan man have en union i en sub-select? (Ellers kan man
>naturligvis sætte klausulen på begge selects.)

Yeps, du har selvfølgelig ret i det med parenteserne.

Og jeg kan ikke forestille mig, at man ikke kan lave unions i subselects:

mysql> SELECT * FROM (SELECT 1 UNION SELECT 2) a\G
*************************** 1. row ***************************
1: 1
*************************** 2. row ***************************
1: 2
2 rows in set (0.00 sec)

Eller hvis man ikke bryder sig om at select'e ind fra den blå luft:
SELECT * FROM (SELECT 1 FROM DUAL UNION ALL SELECT 2 FROM DUAL) a


--
- Peter Brodersen
Kendt fra Internet

Kristian Damm Jensen (23-04-2008)
Kommentar
Fra : Kristian Damm Jensen


Dato : 23-04-08 08:26

Peter Brodersen wrote:
<snip>
> Og jeg kan ikke forestille mig, at man ikke kan lave unions i
> subselects:

<snip eksempel>

Så blev jeg så meget klogere. Tak.

--
Venlig hilsen /Best regards
Kristian Damm Jensen



Søg
Reklame
Statistik
Spørgsmål : 177578
Tips : 31968
Nyheder : 719565
Indlæg : 6409072
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste