Har ett system där man bokar in sig till aktiviteter. Varje aktivitet har ett start och ett slutdatum. Nu behöver jag blockera vid bokning så man aldrig ska kunna boka in sig till två aktiviteter där start -och slutdatum krockar på något sätt.
Hittills har jag kört en BETWEEN sats och kollat om tidigare bokad plats _slutdatum_ ligger mellan ny aktivitets start -och slutdatum, men har visat sig inte vara 100%-igt.
Så, hur ska jag göra istället? Tänker mig något liknande det här:
...
WHERE REDAN_BOKAD_AKT_START >= NY_AKT_START OCH REDAN_BOKAD_AKT_SLUT <= NY_AKT_SLUT
Blir det rätt? Det ska alltså fungera så att om jag redan är inbokad på en aktivitet som pågår 1'a - 10'e Augusti, så ska 1-10 Aug vara "låsta" datum, jag ska endast kunna boka in mig på en grupp som inte ligger inom samma period som en redan bokad aktivitet.
Har nu provat med frågan där men det fungerar inte i mitt fall. Förutom datumen har jag ett gäng andra parametrar. T.e.x. så tillhör varje aktivitet en kategori (section_id) och den ska bara kolla på samma användare som försöker boka igen.
Såhär ser det ut:
SELECT
a.`not_id`,
b.`group_id`
FROM `school_notifies` a
INNER JOIN `school_group` b
ON a.`not_group_id` = b.`group_id`
INNER JOIN `school_level` c
ON b.`group_parent` = c.`level_id`
INNER JOIN `school_type` d
ON c.`level_parent` = d.`type_id`
INNER JOIN `school_section` e
ON d.`type_parent` = e.`section_id`
WHERE a.not_user_id = 1
AND a.`not_type` = 1
AND a.`not_confirmed` IS NOT NULL
AND e.`section_id` = 3
AND <START> BETWEEN b.`group_start` AND b.`group_end`
OR <SLUT> BETWEEN b.`group_start` AND b.`group_end`
Det fungerar _nästan_. Har jag redan en bokning som sträcker sig från 2011-09-01 till 2011-10-31 så får jag fortfarande boka 2011-08-01 till 2011-12-01.
Det ska ju inte fungera, eftersom den perioden sträcker sig över min tidigare bokning.
Så som du har skrivit frågan räcker det med att villkoret <SLUT> BETWEEN b.`group_start` AND b.`group_end` stämmer för att du ska få träff. Är det det du vill? Gruppera annars med parenteser. Kan det möjligen vara så att du vill att alla de första villkoren skall uppfyllas, samt (minst) ett av de två sista?
WHERE a.not_user_id = 1
AND a.`not_type` = 1
AND a.`not_confirmed` IS NOT NULL
AND e.`section_id` = 3
AND [b]([/b]<START> BETWEEN b.`group_start` AND b.`group_end`
OR <SLUT> BETWEEN b.`group_start` AND b.`group_end`[b])[/b]
Kan det möjligen vara så att du vill att alla de första villkoren skall uppfyllas, samt (minst) ett av de två sista?
WHERE a.not_user_id = 1
AND a.`not_type` = 1
AND a.`not_confirmed` IS NOT NULL
AND e.`section_id` = 3
AND [b]([/b]<START> BETWEEN b.`group_start` AND b.`group_end`
OR <SLUT> BETWEEN b.`group_start` AND b.`group_end`[b])[/b]
Ja, precis det vill jag!
Problemet just nu (som du säger) är ju att det blir fel, de datum man redan är bokad på ska "låsas" från vidare bokning (inom samma kategori), oavsett om det är start, slut eller hela perioden som på något vis krockar. Man ska däremot kunna boka plats för aktivitet som startar _efter_ tidigare boknings slutdatum, eller som slutar _före_ en redan bokad plats startdatum.
Jo, men det blir fortfarande fel. Vi kör ett exempel...
- Jag är bokad till aktivitet 2011-09-01 - 2011-10-30.
- Alla grupper vars start -eller slutdatum ligger inom dom två ska inte vara tillåtna.
I nuläget får jag boka in mig på aktivitet som pågår 2011-08-31 - 2011-12-01, eftersom både dom ligger före resp. efter start -och slutdatum på den redan bokade aktiviten.
Så frågan är, hur skyddar jag mig även mot detta scenario?
/R Min fråga ser ut såhär nu:
...
WHERE a.not_user_id = 1
AND a.`not_type` = 1
AND a.`not_confirmed` IS NOT NULL
AND e.`section_id` = 3
AND
(
'2011-08-31' BETWEEN b.`group_start` AND b.`group_end`
OR
'2011-12-01' BETWEEN b.`group_start` AND b.`group_end`
)
Nu vände jag lite på frågan, nu blockeras även anmälan till aktivitet med datumen ovan. Frågan är vad jag förstört istället, ska testa lite mer..
...
WHERE a.not_user_id = 1
AND a.`not_type` = 1
AND a.`not_confirmed` IS NOT NULL
AND e.`section_id` = 3
AND
(
b.`group_start` BETWEEN '2011-08-01' AND '2011-08-31'
OR
b.`group_end` BETWEEN '2011-08-01' AND '2011-08-31'
)
Nepp, blir såklart samma sak fast tvärtom, vilket är ännu sämre än det tidigare caset.
Finns det något sätt att lösa det här med en fråga, eller måste jag använda flera?
/R
Lade till ett extra OR-villkor:
...
WHERE a.not_user_id = 1
AND a.`not_type` = 1
AND a.`not_confirmed` IS NOT NULL
AND e.`section_id` = 3
AND (
b.`group_start` BETWEEN '2011-12-02' AND '2011-12-15'
OR
b.`group_end` BETWEEN '2011-12-02' AND '2011-12-15'
)
OR
(
'2011-12-02' BETWEEN b.`group_start` AND b.`group_end`
OR '2011-12-15' BETWEEN b.`group_start` AND b.`group_end`
)
Nej, som du har skrivit nu så räcker det med att det sista villkoret (din sista parentes) uppfylls. Sätt parenteser runt hela OR-villkoret.
AND
(
(
b.`group_start` BETWEEN '2011-12-02' AND '2011-12-15'
OR
b.`group_end` BETWEEN '2011-12-02' AND '2011-12-15'
)
OR
(
'2011-12-02' BETWEEN b.`group_start` AND b.`group_end`
OR '2011-12-15' BETWEEN b.`group_start` AND b.`group_end`
)
)
Hmm, något är lurt här.. Så här såg frågan ut från början (efter att jag gjort alla ändringar):
SELECT
a.`not_id`, a.`not_type`, a.`not_confirmed`,
b.`group_id`
FROM `school_notifies` a
INNER JOIN `school_group` b
ON a.`not_group_id` = b.`group_id`
INNER JOIN `school_level` c
ON b.`group_parent` = c.`level_id`
INNER JOIN `school_type` d
ON c.`level_parent` = d.`type_id`
INNER JOIN `school_section` e
ON d.`type_parent` = e.`section_id`
WHERE a.`not_confirmed` IS NOT NULL
AND a.not_user_id = 1
AND e.`section_id` = 3
AND
(
(
b.`group_start` BETWEEN '2011-10-31' AND '2011-11-01'
OR
b.`group_end` BETWEEN '2011-10-31' AND '2011-11-01'
)
)
OR
(
(
'2011-10-31' BETWEEN b.`group_start` AND b.`group_end`
OR
'2011-11-01' BETWEEN b.`group_start` AND b.`group_end`
)
)
Upptäckte dock den hämtar rader oavsett användare, kategori eller om "not_confirmed" är NULL eller inte, vad beror det på?
Ändrade till det här:
SELECT
a.`not_id`, a.`not_type`, a.`not_confirmed`,
b.`group_id`
FROM `school_notifies` a
INNER JOIN `school_group` b
ON a.`not_group_id` = b.`group_id`
AND a.`not_confirmed` IS NOT NULL
AND a.not_user_id = 1
INNER JOIN `school_level` c
ON b.`group_parent` = c.`level_id`
INNER JOIN `school_type` d
ON c.`level_parent` = d.`type_id`
INNER JOIN `school_section` e
ON d.`type_parent` = e.`section_id`
WHERE
(
(
b.`group_start` BETWEEN '2011-10-31' AND '2011-11-01'
OR
b.`group_end` BETWEEN '2011-10-31' AND '2011-11-01'
)
)
OR
(
(
'2011-10-31' BETWEEN b.`group_start` AND b.`group_end`
OR
'2011-11-01' BETWEEN b.`group_start` AND b.`group_end`
)
)
AND e.`section_id` = 3
Alltså lade min WHERE-villkor som AND på "JOINEN" istället och då fungerar det.
Vad beror det här på? Är det någon GROUP BY eller så som saknas som orsakar det här?