Ik heb een nieuws-module waarbij de gebruiker kan invullen tussen welke periode het artikel getoond moet worden.
Indien ze dit niet willen gaat wordt er een standaard tijds aanduiding gegeven, 0000-00-00 00:00:00

Nu werkt dit op zich goed. Alleen als ik een bepaalde taal maar wil tonen gaat het mis.
Ik werk met Codeigniter en active record queries. Desalniettemin kan ik gewoon normale queries gebruiken of een combo hiervan.

Onderstaand de query en het resultaat hiervan in objecten.
Ik kom er niet meer uit.


SELECT `news_id`, `news_publishdate`, `news_startdate`, `news_enddate`, `news_order_id`, `news_status`, `news_posterid`, `news_tags`, `news_translation_id`, `news_translation_intro_title`, `news_translation_intro_text`, `news_translation_intro_image`, `news_translation_detail_title`, `news_translation_detail_text`, `news_translation_detail_image`, `news_translation_newsid`, `news_translation_localeid`, `locale_id`, `locale_code`, `locale_name`, `locale_active`
FROM (`module_news`)
JOIN `module_news_translations` ON `module_news_translations`.`news_translation_newsid`  = `module_news`.`news_id`
JOIN `locales` ON `locales`.`locale_id`  = `module_news_translations`.`news_translation_localeid`
WHERE `news_startdate` <= '2014-08-11 00:00:00' AND news_enddate >= '2014-08-11 00:00:00'
OR `news_startdate` = '0000-00-00 00:00:00' OR news_enddate = '0000-00-00 00:00:00'
AND `news_translation_localeid` = '1'
AND `locale_id` = '1'
AND `news_status` =  '1'
ORDER BY `news_order_id` ASC
LIMIT 10
Array
(
    [0] => stdClass Object
        (
            [news_id] => 4
            [news_publishdate] => 2014-05-21 00:00:00
            [news_startdate] => 0000-00-00 00:00:00
            [news_enddate] => 0000-00-00 00:00:00
            [news_order_id] => 2
            [news_status] => 1
            [news_posterid] => 1
            [news_tags] =>
            [news_translation_id] => 5
            [news_translation_intro_title] => item 1
            [news_translation_intro_text] => Item 1
            [news_translation_intro_image] => 
            [news_translation_detail_title] => Item 1
            [news_translation_detail_text] => Item 1
            [news_translation_detail_image] => 
            [news_translation_newsid] => 4
            [news_translation_localeid] => 1
            [locale_id] => 1
            [locale_code] => nl_NL
            [locale_name] => Dutch
            [locale_active] => 1
        )

    [1] => stdClass Object
        (
            [news_id] => 4
            [news_publishdate] => 2014-05-21 00:00:00
            [news_startdate] => 0000-00-00 00:00:00
            [news_enddate] => 0000-00-00 00:00:00
            [news_order_id] => 2
            [news_status] => 1
            [news_posterid] => 1
            [news_tags] =>
            [news_translation_id] => 6
            [news_translation_intro_title] => Item 1
            [news_translation_intro_text] => Item 1
            [news_translation_intro_image] => 
            [news_translation_detail_title] => News item 1
            [news_translation_detail_text] => ''           
            [news_translation_detail_image] => 
            [news_translation_newsid] => 4
            [news_translation_localeid] => 2
            [locale_id] => 2
            [locale_code] => en_GB
            [locale_name] => English
            [locale_active] => 1
        )

)
Zodra je in de WHERE clause gebruik maakt van AND en OR zonder via haakjes aan te geven hoe die moeten worden uitgevoerd dan vraag je om problemen. Ik durf bijna te wedden dat mysql tot een heel andere volgorde komt dan dat jij wilt.
Ja klopt.
Wat ik wil is alleen de artikelen van een bepaalde taal worden getoond.
Maar dan mag de starttijd niet hoger zijn dan nu en de eindtijd wel of gelijk aan.
OF
Er is helemaal geen datum ingevuld (oftewel 0000-00-00 00:00:00)

Kan je me erbij helpen of een voorbeeld geven? Ik weet niet hoe ik haakjes in de query moet verwerken.

Alvast bedankt.
0000-00-00

dat formaat levert alleen maar problemen op: 0000-00-00 is kleiner dan 2014-08-11 en dus zou er niet getoond moeten worden. Je moet dus allemaal aanpassingen doen om de uitzondering te verwerken.
daarbij is het ook geen geldige datum natuurlijk.

Het is veel handiger om indien niet geset de "waarde" NULL te noteren.
Oke ik ga dat dan even proberen. Ik kom er nog op terug! Ga gelijk aan de gang.

[size=xsmall]Toevoeging op 11/08/2014 15:36:12:[/size]

Rick de Graaff op 11/08/2014 15:34:08

Oke ik ga dat dan even proberen. Ik kom er nog op terug! Ga gelijk aan de gang.


Daar heb je het eerste probleem al. Ik gebruik een date-time. Hier kan ik geen NULL opgeven, alleen maar een datum of de 0000-00-00 00:00:00 notatie
Dat laatste is onzin Rick, je kan gewoon NULL invoeren, ook voor een datetime. Alleen als je er een 'NOT NULL' op hebt staan kan dat niet, maar dat is dan jouw keuze.

De haakjes gebruik je om aan te geven welke operator als eerste uitgevoerd moet worden. AND wordt door mysql eerst uitgevoerd, daarna pas een OR. Wat je nu hebt wordt dus:

WHERE `news_startdate` <= '2014-08-11 00:00:00' AND news_enddate >= '2014-08-11 00:00:00'
OR `news_startdate` = '0000-00-00 00:00:00' OR news_enddate = '0000-00-00 00:00:00'
AND `news_translation_localeid` = '1'
AND `locale_id` = '1'
AND `news_status` =  '1'

is gelijk aan:

WHERE (`news_startdate` <= '2014-08-11 00:00:00' AND news_enddate >= '2014-08-11 00:00:00')
  OR 
  `news_startdate` = '0000-00-00 00:00:00' 
  OR 
  (news_enddate = '0000-00-00 00:00:00' AND `news_translation_localeid` = '1' AND `locale_id` = '1' AND `news_status` =  '1')

Ik denk dat je wil:

WHERE (`news_startdate` <= '2014-08-11 00:00:00' AND news_enddate >= '2014-08-11 00:00:00' OR  `news_startdate` = '0000-00-00 00:00:00' OR news_enddate = '0000-00-00 00:00:00')
  AND `news_translation_localeid` = '1' 
  AND `locale_id` = '1' 
  AND `news_status` =  '1'

En dan heb je meteen je haakjes.
@erwin -
Ik kan echt geen NULL waarde opgeven. Ik gebruik Navicat om mijn database te beheren maar het lukt echt niet. Toch heb ik je advies opgevolgd en gekeken of ik iets kon bereiken met de voorbeelden die je gaf.

Uiteindelijke heeft dit het gedaan! :D


SELECT `news_id`, `news_publishdate`, `news_startdate`, `news_enddate`, `news_order_id`, `news_status`, `news_posterid`, `news_tags`, `news_translation_id`, `news_translation_intro_title`, `news_translation_intro_text`, `news_translation_intro_image`, `news_translation_detail_title`, `news_translation_detail_text`, `news_translation_detail_image`, `news_translation_newsid`, `news_translation_localeid`, `locale_id`, `locale_code`, `locale_name`, `locale_active`, `cmsu_id`, `cmsu_username`, `cmsu_emailaddress`, `cmsu_firstname`, `cmsu_lastname`
FROM (`module_news`)
JOIN `module_news_translations` ON `module_news_translations`.`news_translation_newsid`  = `module_news`.`news_id`
JOIN `locales` ON `locales`.`locale_id`  = `module_news_translations`.`news_translation_localeid`
JOIN `cms_users` ON `cms_users`.`cmsu_id`  = `module_news`.`news_posterid`
WHERE (news_startdate <= '2014-08-11 00:00:00' AND news_enddate >= '2014-08-11 00:00:00' OR news_startdate = '0000-00-00 00:00:00' OR news_enddate = '0000-00-00 00:00:00')
AND `news_translation_localeid` = '1'
AND `locale_id` = '1'
AND `news_status` =  '1'
ORDER BY `news_order_id` ASC
LIMIT 10
probeer je NULL op te slaan, of 'NULL' (een string van 4 letters)?
Rick de Graaff op 11/08/2014 15:56:23

@erwin -
Ik kan echt geen NULL waarde opgeven. Ik gebruik Navicat om mijn database te beheren maar het lukt echt niet.

Spijt me, maar het blijft onzin. Een datetime type in mysql heeft geen NULL restrictie erop zitten, dus je kan wel degelijk de waarde NULL invoeren. Dat je bepaalde tools hebt die dat blijkbaar niet kunnen, of je een verkeerd script gebruikt doet daar niets aan af. Lijkt me meer dat er via een bepaald tool een NOT NULL definitie op de kolom wordt gezet, maar dat nogmaals, is iets dat je dan zelf doet.

Ivo P op 11/08/2014 15:33:18

0000-00-00

dat formaat levert alleen maar problemen op: 0000-00-00 is kleiner dan 2014-08-11 en dus zou er niet getoond moeten worden. Je moet dus allemaal aanpassingen doen om de uitzondering te verwerken.
daarbij is het ook geen geldige datum natuurlijk.

Het is veel handiger om indien niet geset de "waarde" NULL te noteren.

Dat 0000-00-00 geen geldig datum is heb je gelijk in, maar:

SELECT NULL < '2014-08-30'
-> NULL
SELECT '0000-00-00' < '2014-08-30'
-> 1

Dus of het nu veel handiger is om een nullable kolom te hebben valt te bezien.
Weet dat er opgelost achter dit topic staat, maar toch...

@erwin -
Ik kan echt geen NULL waarde opgeven. Ik gebruik Navicat om mijn database te beheren maar het lukt echt niet. Toch heb ik je advies opgevolgd en gekeken of ik iets kon bereiken met de voorbeelden die je gaf.

Zit dat probleem in Navicat of in je mysql server configuratie?
Als ik zo even in de handleiding zit te lezen kan je die optie afdwingen dat een datum 0000-00-00 een mooie error geeft. Ik dacht eerst dat de benaming strict modes was.
Effin, hier heb je de link om zelf eens te kijken of je mysql een fine tune kunt geven. ;)
http://dev.mysql.com/doc/refman/5.0/en/sql-mode.html

Edit, hier zit het allemaal wat beknopter verweven mocht je geen zin hebben om alles door te nemen in de manual. http://www.pfz.nl/wiki/werken-met-mysql/#configuratie-sql-modes

Reageren