Vinnaren i pepparkakshustävlingen!
2011-02-19, 12:27
  #1
Medlem
Är relativt ny på sånt här och jag behöver få hjälp en SELECT.

Från ett sökformulär kommer $stad och $tjänst.
$stad jämför bara med kolumnen "stad" och fungerar.
Men "tjänst" är inte en kolumn utan kan namn på olika kolumner t.ex. 1-3.

ID - username - password - stad - tjänstA - tjänstB - tjänstC
01 - usernam1 - passwor1 - sta1 - tjänst1 - tjänst1 - tjänst1
02 - usernam2 - passwor2 - sta2 - [ tom ] - tjänst2 - tjänst2
03 - usernam3 - passwor3 - sta3 - tjänst3 - tjänst3 - tjänst3

Jag vill få ut de rader där $stad=stad och $tjänst kolumnen inte är tom. (vilken tjänst som nu är sökt)

Så här: SELECT * FROM sj_users WHERE stad = '$stad' AND '$tjänst' IS NOT NULL
Sökte jag t.ex på tjänstA här skulle jag få ut ID 01 och 03, inte 02 för den är tom på tjänstA.

ah shit jag fattar iaf!!
Enormt tacksam för hjälp!
Citera
2011-02-19, 13:46
  #2
Medlem
kh31d4rs avatar
kanske borde överväga en normalisering av din modell?
Citera
2011-02-19, 13:46
  #3
Medlem
gadzooxs avatar
SELECT * FROM sj_users WHERE stad='$stad' AND tjänstA IS NOT NULL and tjänstB IS NOT NULL and tjänstC IS NOT NULL ?

Sen kanske du borde normalisera tabellen.... Läs mer på http://en.wikipedia.org/wiki/Join_%28SQL%29


Edit: Eh glöm ovan query... Missade att du skrev att $tjänst = 'tjänstA'. Men normalisering borde du kolla på.

Edit 2: Ok då, du får ett exempel..
Tabell sj_users (ID, username, password, stad)
Tabell user_service (UserID, ServiceID)
Tabell service (ServiceID, ServiceName)

SELECT u.*, s.ServiceName
FROM sj_users u
INNER JOIN user_service us ON u.ID = us.UserID
INNER JOIN service s ON us.ServiceID = s.ServiceID
WHERE s.ServiceName = '$tjänst';
__________________
Senast redigerad av gadzoox 2011-02-19 kl. 13:51.
Citera
2011-02-20, 12:10
  #4
Medlem
Citat:
Ursprungligen postat av gadzoox
SELECT * FROM sj_users WHERE stad='$stad' AND tjänstA IS NOT NULL and tjänstB IS NOT NULL and tjänstC IS NOT NULL ?

Sen kanske du borde normalisera tabellen.... Läs mer på http://en.wikipedia.org/wiki/Join_%28SQL%29


Edit: Eh glöm ovan query... Missade att du skrev att $tjänst = 'tjänstA'. Men normalisering borde du kolla på.

Edit 2: Ok då, du får ett exempel..
Tabell sj_users (ID, username, password, stad)
Tabell user_service (UserID, ServiceID)
Tabell service (ServiceID, ServiceName)

SELECT u.*, s.ServiceName
FROM sj_users u
INNER JOIN user_service us ON u.ID = us.UserID
INNER JOIN service s ON us.ServiceID = s.ServiceID
WHERE s.ServiceName = '$tjänst';

Nu blev det genast svårt. Men det gillar jag. Jag håller på att lär mig och lär mig en sak i taget efter problem jag stöter på. Får ofta göra om när jag kommer på saker i efterhand som är enklare.
Är detta verkligen det enklaste sättet att göra detta?

Tjänster kommer bli fler eller färre, värdet i en tjänstkolumn kommer vara en kommentar till tjänsten för den användaren. Och som sagt namnet på kolumnen är namnet på tjänsten. Det kanske blir 30 kolumner tillslut.

Jag har även sj_tjanster där jag listar samma tjänster manuellt, för att hämta till t.ex dropdowns.

Ge mig gärna endast sökord för hur jag kan hitta bättre alternativ, söker inte en komplett lösning för det kostar ofta mycket pengar

Jag ska kolla upp "normalisering"!
Citera
2011-02-20, 15:04
  #5
Medlem
gadzooxs avatar
Citat:
Ursprungligen postat av SiKth
Tjänster kommer bli fler eller färre, värdet i en tjänstkolumn kommer vara en kommentar till tjänsten för den användaren. Och som sagt namnet på kolumnen är namnet på tjänsten. Det kanske blir 30 kolumner tillslut.
Just därför bör du normalisera tabellen, dess struktur bör inte förändras pga att datat gör det.

Se det som att kolumnerna i user-tabellen definierar vem en användare är, dvs hans egenskaper, inte vad han har. Han är inte en eller 30 tjänster; tjänst X eller Y är inte någon egenskap hos själva användaren. Han har däremot en eller 30 tjänster och de bör därför ligga i en separat tabell.

Kommentaren kan du då flytta till user_service-tabellen:
Tabell user_service (UserID, ServiceID, Kommentar)

Din tabell "sj_tjanster" motsvaras nog av min tabell "service".

Att normalisera gör det dessutom plötsligt väldigt lätt att ta reda på vilka användare som har tjänst X:
SELECT u.*
FROM sj_users u
INNER JOIN user_service us ON u.UserID = us.UserID
WHERE us.ServiceID = 15; -- eller joina in service-tabellen också, och ha tjänstens namn som sökkriterium.

Eller hur många tjänster varje användare har:
SELECT u.Username, COUNT(us.*) AS AntalTjänster
FROM sj_users u
INNER JOIN user_service us on u.UserID = us.UserID
GROUP BY u.Username
Citera
2011-02-22, 21:55
  #6
Medlem
Citat:
Ursprungligen postat av gadzoox
Just därför bör du normalisera tabellen, dess struktur bör inte förändras pga att datat gör det.

Se det som att kolumnerna i user-tabellen definierar vem en användare är, dvs hans egenskaper, inte vad han har. Han är inte en eller 30 tjänster; tjänst X eller Y är inte någon egenskap hos själva användaren. Han har däremot en eller 30 tjänster och de bör därför ligga i en separat tabell.

Kommentaren kan du då flytta till user_service-tabellen:
Tabell user_service (UserID, ServiceID, Kommentar)

Din tabell "sj_tjanster" motsvaras nog av min tabell "service".

Att normalisera gör det dessutom plötsligt väldigt lätt att ta reda på vilka användare som har tjänst X:
SELECT u.*
FROM sj_users u
INNER JOIN user_service us ON u.UserID = us.UserID
WHERE us.ServiceID = 15; -- eller joina in service-tabellen också, och ha tjänstens namn som sökkriterium.

Eller hur många tjänster varje användare har:
SELECT u.Username, COUNT(us.*) AS AntalTjänster
FROM sj_users u
INNER JOIN user_service us on u.UserID = us.UserID
GROUP BY u.Username


Nu har jag läst på en del om det här. Nu inser jag vilket strul jag hade ställt till för mig själv om jag fortsatt på samma banna med en ända tabell!

Så om jag nu har delat upp det hela i olika tabeller som jag nu lärt. Hur "kopplar" jag dessa samman?

Hur får jag in t.ex. UserID från sj_users in i Service tabellen? ID ska vara samma nummer i båda för samma användare? Eller görs detta inte förren i SELECT:en?

Jag läser vidare..

Tack så mycket!
Citera
2011-02-24, 07:25
  #7
Medlem
Citat:
Ursprungligen postat av SiKth
Nu har jag läst på en del om det här. Nu inser jag vilket strul jag hade ställt till för mig själv om jag fortsatt på samma banna med en ända tabell!

Så om jag nu har delat upp det hela i olika tabeller som jag nu lärt. Hur "kopplar" jag dessa samman?

Hur får jag in t.ex. UserID från sj_users in i Service tabellen? ID ska vara samma nummer i båda för samma användare? Eller görs detta inte förren i SELECT:en?

Jag läser vidare..

Tack så mycket!

Du använder en främmande nyckel (foreign key). I Serivce tabellen skapar du ett attribut som förslagsvis heter fk_UserID. Sen får du skriva säga att dom har en relation. Har inte kommandot i huvet för mysql men är väl något med altertable och sen säga vilken som är primärnyckel och vilken som är främmandenyckel.
Citera
2011-02-24, 23:46
  #8
Medlem
Citat:
Ursprungligen postat av PerWi
Du använder en främmande nyckel (foreign key). I Serivce tabellen skapar du ett attribut som förslagsvis heter fk_UserID. Sen får du skriva säga att dom har en relation. Har inte kommandot i huvet för mysql men är väl något med altertable och sen säga vilken som är primärnyckel och vilken som är främmandenyckel.

Hahah, efter flera timmar av att försöka sätta upp en koppling mellan tabllerna så inser jag att min webhost, One.com inte stödjer InnoDB och alltså inte heller Foreign Keys.

Hur gör jag då?

Min tanka var ju nu något sånt här:

tabell "user"
username - password - email - ..
Lars Larsson - abc1234 - lars @ gmail.com

tabell "tjanster"
username - tjanst1 - tjanst2 - tjanst3 - ..
Lars Larsson - kommentar1 - kommentar2 - kommentar3 - ..

Och koppla ihop username med varandra.

Är det en dum lösning?
Det måste finnas en annan nu när foreign keys inte fungerar.

Huvudsaken är att man genom ett sökforumlär ska "solla" ut de användare MED en kommentar i en tjänst.
Citera
2011-02-25, 09:51
  #9
Medlem
Det låter ju helt sjukt att du inte kan använda FK i din databas. Stämmer verkligen det är det bara att byta webbhotell. Binero är bra!

Det som är problemet med din koppling är att attributen du kopplar ihop inte är unika. Vad händer om det kommer en till person som har samma namn. Man brukar koppla med ett unikt id, antingen en s.k. GUID eller en INT med auto_increment så att det bara finns en unik.

Förstår inte riktigt hur du har tänkt att koppla det där, du måste väl ändå sätta en relation mellan dem? I ditt fall UserName. Blir väl samma problematik?

tabell "user"
ID - username - password - email - ..
Lars Larsson - abc1234 - lars @ gmail.com

tabell "tjanster"
ID - username - tjanst1 - tjanst2 - tjanst3 - ..
Lars Larsson - kommentar1 - kommentar2 - kommentar3 - ..

alter table `user`
add constraint `ID` foreign key (`ID`) references
`tjanster` (`ID`) on delete cascade on update cascade,

Det där kanske inte blev klockrent, länge sen jag använde mysql, men det är något sånt du borde göra.
Citera
2011-02-25, 11:26
  #10
Medlem
Username ska vara unikt var tanken.

Tyckte och det var konstigt med one.com, men dom kunde inte ge mig en hum om när det var löst. Har haft dom i över 5 år och vill inte byta.

Kan jag göra en select med innerjoin eller liknande utan att ha en foreign key?

Som du säger måste tänka ut en bra design men det är inte lätt eftersom det är första gången.

Tack för hjälpen!
Citera
2011-02-25, 11:58
  #11
Medlem
kh31d4rs avatar
MyISAM "klarar" att ha foregin key constraints också, men den klagar inte när man bryter mot dem. Och ja, du kan göra joins osv utan att attributen är nycklar.
Citera

Stöd Flashback

Flashback finansieras genom donationer från våra medlemmar och besökare. Det är med hjälp av dig vi kan fortsätta erbjuda en fri samhällsdebatt. Tack för ditt stöd!

Stöd Flashback