Avatar billede loevstroem Nybegynder
15. august 2010 - 21:44 Der er 9 kommentarer og
1 løsning

Hjælp til union

Hej Eksperter,

Jeg har brug for hjælp til at få en query skrevet på den rigtige måde :-)

Jeg har to tabeller i min database j_posts & j_external_posts. Jeg er ude efter at hente de nyeste rækker (bestemt af p_post_stamp og ep_post_stamp). Antaller bliver begrænset i min LIMIT. Hvis den henter en række fra j_posts skal der samtidig laves et JOIN på j_blogs for at hente nogle ekstra informationer.

Jeg håber ovenstående giver mening, og der er nogen der forstår mit problem :)


SELECT     b_id, b_name,                         b_subdomain, p_id, p_user_id, p_title, p_text, UNIX_TIMESTAMP(p_post_stamp) AS p_post_stamp FROM j_posts INNER JOIN j_blogs ON p_blog_id = b_id && p_is_draft = '0' WHERE b_approved = 1 UNION SELECT ep_id, ep_blog_id, ep_text, ep_post_stamp FROM j_external_posts ORDER BY (p_post_stamp,ep_post_stamp)  LIMIT $offset, $views_page


På forhånd tak
Avatar billede loevstroem Nybegynder
15. august 2010 - 21:46 #1
Jeg mangler lige at tilføje jeg ikke er ude efter at hente et antal af bestemte rækker fra hver tabel, derimod de nyeste rækker hvis man samler tabellerne. dvs. hvis min LIMIT indeholder 10, og de 7 nyeste rækker ligger i j_posts skal de hentes derfra, og de resterende 3 fra j_external_posts.
16. august 2010 - 11:54 #2
Lad mig proeve at tilnaerme mig et svar.  Jeg bryder det ned i et par trin, foerst denne del af din query: 

SELECT b_id, b_name, b_subdomain, p_id, p_user_id, p_title, p_text, UNIX_TIMESTAMP(p_post_stamp) AS p_post_stamp FROM j_posts INNER JOIN j_blogs ON p_blog_id = b_id && p_is_draft = '0' WHERE b_approved = 1

Det er ikke en korrekt query - hvis du vil have de resultater der ikke er draft og hvor blog er approved skal det vaere:

SELECT b_id, b_name, b_subdomain, p_id, p_user_id, p_title, p_text, UNIX_TIMESTAMP(p_post_stamp) AS p_post_stamp FROM j_posts INNER JOIN j_blogs ON p_blog_id = b_id WHERE p_is_draft = '0' AND  b_approved = 1

Proev om det virker.  Hvis ikke, saa er der maaske et problem med dine datatyper i tabellerne.  Du har p_is_draft = '0' hvilket tyder paa datatype CHAR eller VARCHAR i feltet p_is_draft hvorimod du har b_approved = 1 hvilket tyder paa en INTEGER eller BOOLEAN datatype i feltet b_approved.  Jeg vil anbefale at bruge datatype BOOLEAN (eller BOOL) i begge og skrive p_is_draft = 0.

Trin 2, denne del af din query:

SELECT ep_id, ep_blog_id, ep_text, ep_post_stamp FROM j_external_posts

I sig selv ser det godt ud.

Men Trin 3, at proeve at lave en UNION mellem de to queries.  For at kunne lave UNION mellem to queries skal begge levere samme antal felter og med de samme datatyper.  Din foerste delquery giver 8 felter (b_id, b_navn, b_subdomain, o.s.v.) hvorimod din anden subquery kun giver 4 felter (ep_id, ep_blog_id, ep_text ep_post_stamp).  Er der nogen grund til at du ikke vil have blog information for external posts?  Jeg gaar ud fra at de eksisterer siden du for external posts har en blog_id.  Lad mig faa en tilbagemelding paa dette og eventuelt andre kommentarer, saa fikser vi resten.
Avatar billede loevstroem Nybegynder
16. august 2010 - 12:00 #3
Hej Christian,

Tak for dit svar.

p_is_draft = 1 er INTEGER - en syntax fejl fra min side :)

Din observation er helt korrekt. Jeg kunne sagtens lave et JOIN på j_blogs for at hente de samme kolonner, men det er dog overflødigt da dataen ikke skal bruges. Umiddelbart er mine tabeller j_posts og j_external_posts ikke ens i struktur - kan det løses uden?
16. august 2010 - 12:11 #4
Et hurtigt svar:  Du kan ikke lave en union query uden at have samme struktur i alle delqueries, men du kan fylde tomme data ind.  Jeg skal proeve at lave et eksempel i eftermiddag.
16. august 2010 - 13:53 #5
Ok, tilbage.

Jeg lavede denne query for de external posts der saetter de noedvendige tomme felter ind til at goere UNION muligt.  Eftersom du ikke bruger blog data tillod jeg mig ikke at indsaette ep_blog_id.

SELECT 0, '', '', ep_id, 0, '', ep_text, UNIX_TIMESTAMP(ep_post_stamp) FROM j_external_posts

Det ser maerkelig ud, men det skulle virke.

For saa at kunne ordne din union i tidsraekkefoelge maa du have et faelles navn for tidsfelterne, for eksempel UNIX_TIMESTAMP(p_post_stamp) AS Time og UNIX_TIMESTAMP(ep_post_stamp) As Time.

Saa her er din fulde UNION query:

SELECT b_id, b_name, b_subdomain, p_id, p_user_id, p_title, p_text, UNIX_TIMESTAMP(p_post_stamp) AS Time FROM j_posts INNER JOIN j_blogs ON p_blog_id = b_id WHERE p_is_draft = 0 AND  b_approved = 1
UNION
SELECT 0, '', '', ep_id, 0, '', ep_text, UNIX_TIMESTAMP(ep_post_stamp) AS Time FROM j_external_posts
ORDER BY Time
LIMIT ...[hvad du vil have som limit.]
Avatar billede loevstroem Nybegynder
16. august 2010 - 14:15 #6
Du er genial! Tusind tak for hjælpen :-)
Avatar billede loevstroem Nybegynder
16. august 2010 - 19:46 #7
Jeg håber jeg må forstyrre dig igen :- )

Hvordan laves et COUNT på antal rækker på begge tables?

En mysql_num_rows på nedenstående vil naturligvis returnere det antal af den table der har flest records- og ikke det samlede antal.

SELECT b_id FROM j_posts INNER JOIN j_blogs ON p_blog_id = b_id && p_is_draft = 0 WHERE b_approved = 1 UNION SELECT ep_id FROM j_external_posts INNER JOIN j_blogs ON ep_blog_id = b_id WHERE b_approved = 1
Avatar billede ggxdg Nybegynder
17. august 2010 - 18:05 #8
SELECT COUNT(b_id) AS b_idc,b_id FROM j_posts INNER JOIN j_blogs ON p_blog_id = b_id && p_is_draft = 0 WHERE b_approved = 1 UNION SELECT COUNT(ep_id) AS ep_idc,ep_id FROM j_external_posts INNER JOIN j_blogs ON ep_blog_id = b_id WHERE b_approved = 1

Ovenstående er mit bud.
Jeg ved ikke om det er redindant at tilføje cellerne igen, eller om man kun kan/skal bruge dem 1 gang.

count-variablerne:
$row['b_idc']
$row['ep_idc']
Avatar billede ggxdg Nybegynder
17. august 2010 - 18:06 #9
redindant = redundant
17. august 2010 - 19:02 #10
loevstroem, jeg havde ikke set at du havde tilfoejet et spoergsmaal.  Jeg holder nornmalt ikke saa meget oeje med de spoergsmaal der er blevet lukket.  Det er normalt bedst at oprette et nyt spoergsmaal, saa bliver det set af alle medlemmerne.  Heldigvis saa ggxdg dette tillaegsspoergsmaal.  Jeg har ikke noget at tilfoeje.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester