Avatar billede axkris Nybegynder
29. januar 2004 - 17:15 Der er 13 kommentarer og
1 løsning

Select med join virker ikke

Hej

Hjææælp :-D

Oprindeligt havde jeg to select-sætninger, starten med følende, som finder de aktuelle artikler/links:

strSQL="select * FROM LINKS_FSH WHERE Email_sent = 'false' and Publish between '" & alternativeDate2(date()-4) & "' and '" & alternativeDate() & "' AND TYPE <> 'CHAT'"
set rs1 = dataConn.execute(strSQL)

Når de disse artikler er fundet, så skal email-adresserne på de folk, som har skrevet de disse artikler, findes:

do while not rs1.BOF or not rs1.EOF
  strSQL="select * FROM FORUM_MEMBERS WHERE MEMBER_ID = " & rs1("MemberID")
  set rs2 = dataConn.execute(strSQL)

Og det virker fint, men jeg vil gerne have kørt dem sammen i en sætning, så jeg prøvede:

strSQL="SELECT FORUM_MEMBERS.Member_ID, FORUM_MEMBERS.M_EMAIL, FORUM_MEMBERS.M_FIRSTNAME, FORUM_MEMBERS.M_LASTNAME, FSH_LINKS.TITLE, FSH_LINKS.TYPE left join FORUM_MEMBERS.Member_ID = LINKS_FSH.MemberID WHERE LINKS_FSH.Email_sent = 'false' and LINKS_FSH.Publish between '" & alternativeDate2(date()-4) & "' and '" & alternativeDate() & "' AND LINKS_FSH.TYPE <> 'CHAT'"

Men den brokker sig over den måde jeg joiner på.... og det kan jeg da slet ikke forstå, så go jeg er til sql ;-)

Kan du hjælpe mig :-D
Avatar billede axkris Nybegynder
29. januar 2004 - 17:18 #1
You have an error in your SQL syntax near 'left join FORUM_MEMBERS.Member_ID = LINKS_FSH.MemberID WHERE LINKS_FSH.Email_sen' at line 1
Avatar billede gertnissen Nybegynder
29. januar 2004 - 17:25 #2
Du mangler FROM i din SQL

Noget ala dette skal du bruge istedet for

strSQL="SELECT FORUM_MEMBERS.Member_ID
            , FORUM_MEMBERS.M_EMAIL
            , FORUM_MEMBERS.M_FIRSTNAME
            , FORUM_MEMBERS.M_LASTNAME
            , FSH_LINKS.TITLE
            , FSH_LINKS.TYPE
FROM FORUM_MEMBERS
    left join
    LINKS_FSH
    on FORUM_MEMBERS.Member_ID = LINKS_FSH.MemberID
WHERE LINKS_FSH.Email_sent = 'false'
  and LINKS_FSH.Publish between '" & alternativeDate2(date()-4) & "'
  and '" & alternativeDate() & "'
  AND LINKS_FSH.TYPE <> 'CHAT'"
Avatar billede axkris Nybegynder
29. januar 2004 - 17:42 #3
Den kører i en evighed uden der sker noget:

SELECT FORUM_MEMBERS.Member_ID , FORUM_MEMBERS.M_EMAIL , FORUM_MEMBERS.M_FIRSTNAME , FORUM_MEMBERS.M_LASTNAME , LINKS_FSH.TITLE , LINKS_FSH.TYPE FROM FORUM_MEMBERS left join LINKS_FSH ON FORUM_MEMBERS.Member_ID = LINKS_FSH.MemberID WHERE LINKS_FSH.Email_sent = 'false' AND LINKS_FSH.Publish between '2004-01-25' AND '2004-01-29' AND LINKS_FSH.TYPE <> 'CHAT'
Avatar billede gertnissen Nybegynder
29. januar 2004 - 17:50 #4
Tja, har du mange rækker og/eller har du index på Member_ID ?

Prøv med
strSQL="SELECT FORUM_MEMBERS.Member_ID
            , FORUM_MEMBERS.M_EMAIL
            , FORUM_MEMBERS.M_FIRSTNAME
            , FORUM_MEMBERS.M_LASTNAME
            , FSH_LINKS.TITLE
            , FSH_LINKS.TYPE
FROM FORUM_MEMBERS
  , LINKS_FSH
WHERE FORUM_MEMBERS.Member_ID = LINKS_FSH.MemberID
  and LINKS_FSH.Email_sent = 'false'
  and LINKS_FSH.Publish between '" & alternativeDate2(date()-4) & "' and '" & alternativeDate() & "'
  AND LINKS_FSH.TYPE <> 'CHAT'"

Det kræver blot at alle member_id findes i begge tabeller, ellers vil du komme mangle dem uden hit fra forum_members.
Avatar billede gertnissen Nybegynder
29. januar 2004 - 17:53 #5
Normalt vil man vende left join således at du først skrive 'grundtabellen' og efter left join den tabel du vil berige den første den første med.

ala
FROM LINKS_FSH
    left join
    FORUM_MEMBERS
    on LINKS_FSH.MemberID  = FORUM_MEMBERS.Member_ID

Mit første svar var blot til inspiration ikke cut&paste
Avatar billede axkris Nybegynder
29. januar 2004 - 18:04 #6
Det virker faktisk nu, men den er utrolig langsom (100 gange langsommere end det oprindeligt script, som ses helt i toppen af mit indlæg).

>har du mange rækker
1500 i FORUM_MEMBERS og 5000 i FSH_LINKS

>har du index på Member_ID
datatypen på både ID i både LINKS_FSH og FORUM_MEMBERS PRIMARY og INDEX

>member_id findes i begge tabeller
Måske kan fejlen ligger i, at artikler (LINKS_FSH) ikke nødvendigvis har tilknyttet en forfatter (FORUM_MEMBERS), fordi man godt kan have lov til at være anonym.

CREATE TABLE LINKS_FSH (
  ID int(11) NOT NULL auto_increment,
  MemberID int(11) NOT NULL default '0',
  CategoryID int(11) NOT NULL default '0',
  Email_sent text NOT NULL,
  Email_to text,
  Url text NOT NULL,
  Title text NOT NULL,
  Picture text NOT NULL,
  Description text NOT NULL,
  Type text NOT NULL,
  Language text NOT NULL,
  Publish date NOT NULL default '0000-00-00',
  Created date NOT NULL default '0000-00-00',
  FSH text NOT NULL,
  PRIMARY KEY  (ID),
  KEY ID (ID)
) TYPE=MyISAM;


CREATE TABLE FORUM_MEMBERS (
  MEMBER_ID int(11) NOT NULL auto_increment,
  M_STATUS smallint(6) default '0',
  M_NAME varchar(75) default '',
  M_USERNAME varchar(150) default '',
  M_PASSWORD varchar(65) default '',
  M_EMAIL varchar(50) default '',
  M_COUNTRY varchar(50) default '',
  M_HOMEPAGE varchar(255) default '',
  M_SIG text,
  M_VIEW_SIG smallint(6) default '1',
  M_SIG_DEFAULT smallint(6) default '1',
  M_DEFAULT_VIEW int(11) default '1',
  M_CHAT_DEFAULT int(11) default '0',
  M_LEVEL smallint(6) default '1',
  M_AIM varchar(150) default '',
  M_ICQ varchar(150) default '',
  M_MSN varchar(150) default '',
  M_YAHOO varchar(150) default '',
  M_POSTS int(11) default '0',
  M_DATE varchar(14) default '',
  M_LASTHEREDATE varchar(14) default '',
  M_LASTPOSTDATE varchar(14) default '',
  M_TITLE varchar(50) default '',
  M_SUBSCRIPTION smallint(6) default '0',
  M_HIDE_EMAIL smallint(6) default '0',
  M_RECEIVE_EMAIL smallint(6) default '1',
  M_LAST_IP varchar(15) default '000.000.000.000',
  M_IP varchar(15) default '000.000.000.000',
  M_FIRSTNAME varchar(100) default '',
  M_LASTNAME varchar(100) default '',
  M_OCCUPATION varchar(255) default '',
  M_SEX varchar(50) default '',
  M_AGE varchar(10) default '',
  M_DOB varchar(8) default '',
  M_HOBBIES text,
  M_LNEWS text,
  M_QUOTE text,
  M_BIO text,
  M_MARSTATUS varchar(100) default '',
  M_LINK1 varchar(255) default '',
  M_LINK2 varchar(255) default '',
  M_CITY varchar(100) default '',
  M_STATE varchar(100) default '',
  M_PHOTO_URL varchar(255) default '',
  M_KEY varchar(32) default '',
  M_NEWEMAIL varchar(50) default '',
  M_PWKEY varchar(32) default '',
  M_SHA256 smallint(6) default '1',
  PRIMARY KEY  (MEMBER_ID),
  KEY FORUM_MEMBERS_MEMBER_ID (MEMBER_ID)
) TYPE=MyISAM;


    strSQL="SELECT FORUM_MEMBERS.Member_ID" & vbNewline & _
            ", FORUM_MEMBERS.M_EMAIL" & vbNewline & _
            ", FORUM_MEMBERS.M_FIRSTNAME" & vbNewline & _
            ", FORUM_MEMBERS.M_LASTNAME" & vbNewline & _
            ", LINKS_FSH.ID " & vbNewline & _
            ", LINKS_FSH.TITLE" & vbNewline & _
            ", LINKS_FSH.TYPE " & vbNewline & _
            ", LINKS_FSH.Email_to " & vbNewline & _
            "FROM FORUM_MEMBERS " & vbNewline & _
            "    left join " & vbNewline & _
            "    LINKS_FSH " & vbNewline & _
            "ON FORUM_MEMBERS.Member_ID = LINKS_FSH.MemberID " & vbNewline & _
            "WHERE LINKS_FSH.Email_sent = 'false'" & vbNewline & _
              "    AND LINKS_FSH.Publish between '" & alternativeDate2(date()-4) & "'" & vbNewline & _
              "    AND '" & alternativeDate() & "'" & vbNewline & _
              "    AND LINKS_FSH.TYPE <> 'CHAT'" 
 
    response.write strSQL
    set rs = dataConn.execute(strSQL)
Avatar billede axkris Nybegynder
29. januar 2004 - 18:05 #7
OUTPUT:
SELECT FORUM_MEMBERS.Member_ID , FORUM_MEMBERS.M_EMAIL , FORUM_MEMBERS.M_FIRSTNAME , FORUM_MEMBERS.M_LASTNAME , LINKS_FSH.ID , LINKS_FSH.TITLE , LINKS_FSH.TYPE , LINKS_FSH.Email_to FROM FORUM_MEMBERS left join LINKS_FSH ON FORUM_MEMBERS.Member_ID = LINKS_FSH.MemberID WHERE LINKS_FSH.Email_sent = 'false' AND LINKS_FSH.Publish between '2004-01-25' AND '2004-01-29' AND LINKS_FSH.TYPE <> 'CHAT'
Avatar billede gertnissen Nybegynder
29. januar 2004 - 18:13 #8
prøv at bytte om på FORUM_MEMBERS og LINKS_FSH i din from/left join

ala

FROM LINKS_FSH
    left join
    FORUM_MEMBERS
    on LINKS_FSH.MemberID  = FORUM_MEMBERS.Member_ID

Normalt vil man vende left join således at du først skrive 'grundtabellen' og efter left join den tabel du vil berige den første den første med. Eller blander jeg left og right join sammen ?
Avatar billede axkris Nybegynder
29. januar 2004 - 18:43 #9
Det virker nu, tryk svar :-D
Avatar billede gertnissen Nybegynder
29. januar 2004 - 18:44 #10
Virkede det at bytte om på rækkefølgen i din join ?  eller....
Avatar billede axkris Nybegynder
29. januar 2004 - 18:47 #11
Ja og mange tak for hjælpen :-D

Hvis du vil have 10 points ekstra, så må du gerne hjælpe mig følgende:

Jeg bruger en hjemme-lavet funktion til at omsætte en dansk dato til en amerikansk dato, men det ville jo gå mere hurtigere, hvis der lå en sådan i MySql.... så kender du sådan en?

...LINKS_FSH.Publish between '" & alternativeDate2(date()-4) & "'...
Avatar billede gertnissen Nybegynder
29. januar 2004 - 19:00 #12
jeg går udfra at publish er af type date i din tabel fremfor timestamp, men jeg har desværre ikke en nem løsning, du vil kunne finde mange høker løsninger i både PHP og ASP kategorierne.

Du skal nok lede efter noget ala

SELECT UNIX_TIMESTAMP(timestamp_felt) AS date FROM tabel
SELECT DATE_FORMAT( tid, '%d/%m %Y %H:%i') AS dato

se evt på http://www.php.net/manual/en/function.mktime.php for generering af timestamp værdier

men det er desværre ikke noget jeg har arbejdet ret meget med
Avatar billede axkris Nybegynder
29. januar 2004 - 19:05 #13
Ok, mange tak for hjælpen :-D
Avatar billede kongsteddk Nybegynder
25. marts 2004 - 23:07 #14
Der findes vel ikke ret mange andre løsninger i ASP end den som følger(?):

Function MySQLDateTime(datetime)
    intYear = year(datetime)
    intMonth = month(datetime)
    intDay = day(datetime)
    intHour = hour(datetime)
    intMinute = minute(datetime)
    intSecond = second(datetime)
   
    if intMonth < 10 then intMonth = "0"&intMonth end if
    if intDay < 10 then intDay = "0"&intDay end if
    if intHour < 10 then intHour = "0"&intHour end if
    if intMinute < 10 then intMinute = "0"&intMinute end if
    if intSecond < 10 then intSecond = "0"&intSecond end if
   
    strOut = intYear & intMonth & intDay & intHour & intMinute & intSecond
    MySQLDateTime = strOut
End Function
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