Avatar billede Mik2000 Professor
14. april 2015 - 01:14 Der er 7 kommentarer og
1 løsning

Avanceret SQL

Hej

Har brug for en der er virkelig dygtig til SQL

Jeg har 4 tabeller i et besked system hvor man kan sende beskeder til hinanden, og der kan være flere i en samtale

------------------
messages
------------------
m_id
m_subject

------------------
messages_sub
------------------
ms_id
ms_m_id (message id)
ms_u_id (user id)
ms_message
ms_datetime

------------------
messages_con_users
------------------
mcu_id
mcu_m_id (message id)
mcu_u_id (user id)
mcu_is_read

------------------
users
------------------
u_id
u_name

------------------

Jeg vil gerne hente ud fra messages hvor u_id = en special brugerid (dvs. alle samtaler hvor den person deltager)

Jeg vil gerne have mcu_read ud (dvs. om den specielle bruger har læst tråden 0 eller 1)

Samtidige ønsker jeg sidste nye besked fra message_sub (f.eks. max(ms_datetime)) (dvs. sidste besked i tråden uanset hvem der har skrevet den)

Samtidige ønsker jeg u_name på den bruger der har skrevet den sidste nye besked (ms_u_id fra max(ms_datetime)) (dvs. brugernavn på den der har skrevet sidste indlæg i tråden)

Således at jeg får en række med følgende:
- m_subject (emne på beskeden)
- mcu_is_read (indeholder om bruger har læst besked)
- ms_message (max - dvs. sidste nye besked i tråden - ms_m_id = m_id)
- ms_datetime (max - sidste nye dato i tråden (på ovenstående besked) - ms_m_id = m_id)
- u_name (Brugernavn på den der har skrevet sidste nye indlæg i tråden)

Kan man lave en sætning der henter de ting (ser ikke grund til at lave flere, da det jo kun er en row med data, og da jeg samtidige skal kunne sortere det)

Men det er pænt svært at gennemskue hvordan, så håber der er en som er virkelig god til SQL der kan hjælpe mig :)
Avatar billede vagnk Juniormester
14. april 2015 - 09:56 #1
Uden at jeg anser mig selv som "virkelig dygtig til SQL" vil jeg gerne komme med nogle indledende betragtninger.

Du har postet dit spørgsmål her i "MySQL". Skulle det i virkeligheden være postet i den overordnede gruppe "Databaser"? Eller er det rent faktisk en MySQL?

Hovedideen er at lade bassen lave det arbejde den er god og så tage sig af detaljer som præsentation i dit script.

Dine tabeller ser ud til at være godt normaliserede, og det er effektivt i DB-sammenhæng, men gør det lidt besværligt at lave queries.

Hvor meget kender du selv til SQL? Kan du lave en JOIN? Ved du hvad en LEFT JOIN laver?

Koder du i php eller andet, således at du eventuelt kan massere data i en løkke?

Har du adgang til en Access-database, som er god for mindre erfarne til at lave queries og views med?

Inden vi går igang kunne jeg forestille mig at et par VIEWS vil kunne hjælpe på overskueligheden.

Det er ikke en opgave man lige kan ryste ud af ærmet, så hvis du lagde nogle testdata ind i dine tabeller, ville vi have det samme udgangspunkt når vi skal udveksle synspunkter.
Avatar billede gnoname Praktikant
14. april 2015 - 11:30 #2
Hvis du erstatter XXXX i det følgende med den brugerid, du ønsker at undersøge, skulle det kunne gøre det:

SELECT m.m_subject,
      mcu.mcu_is_read,
      ms1.ms_message,
      ms1.ms_datetime,
      u.u_name
FROM  messages_con_users mcu
JOIN  messages          m
ON    m.m_id = mcu.mcu_m_id
JOIN  messages_sub      ms1
ON    ms1.ms_m_id = m.m_id
JOIN  users              u
ON    u.u_id = ms.ms_u_id
WHERE  ms.ms_datetime = (
        select max(ms_datetime)
        from  messages_sub ms2
        where  ms2.ms_m_id = ms1.ms_m_id)
AND    mcu.mcu_u_id = XXXX
Avatar billede Mik2000 Professor
14. april 2015 - 12:03 #3
VagnK
Det er MySQL
Jeg kan godt lave SQL, kan også lave join, left join, inner join osv. men denne her kunne jeg ikke gennemskue fordi der kun skulle bruges et resultat fra den anden og ikke blot inner joine alle der matcher
Jeg bruger ikke access og jeg koder i PHP

Gnoname
Godt rystet ud af ærmet. Tester det lige og vender tilbage - takker mange gange indtil videre :)
Avatar billede vagnk Juniormester
14. april 2015 - 12:19 #4
Der har du din virkeligt dygtige til SQL-programmør (gnoname)!

Jeg var ved at nærme mig den, men den sidste subquery gør tricket. Hvis du har problemer med gnonames forslag skal du måske kigge på nogle 1-n relationer.

Jeg afstår fra videre indblanding.
Avatar billede Mik2000 Professor
14. april 2015 - 12:31 #5
Gnoname: Det ser ud til at virke med nogle småændringer

WHERE  ms.ms_datetime = ( => WHERE  ms1.ms_datetime = (
ON    u.u_id = ms.ms_u_id => ON    u.u_id = ms1.ms_u_id

Det var godt nok godt klaret, og det er jeg SUPER glad for :) ... har kæmpet længe med den og prøvet en masse forskellige ting :)

Der er selvfølgelig point til dig hvis du lægger et svar :):):):)
Avatar billede Mik2000 Professor
14. april 2015 - 12:33 #6
Vagnk: Dit indlæg kom først efter jeg havde skrevet den sidste (fordi den stod på siden siden jeg skrev det første). Tak for dine input også :)
Avatar billede gnoname Praktikant
14. april 2015 - 13:07 #7
Det er rigtigt - der manglede lige et par 1-taller i aliasserne :-)
Avatar billede Mik2000 Professor
14. april 2015 - 16:44 #8
Men det var i småtingsafdelingen - var nok aldrig kommet frem til det uden din hjælp. Takker :)
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

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