+ Svara på ämne
Sidan 1 av 2 1 2 SistaSista
Resultat 1 till 20 av 32

Ämne: Problematik datumsökning MySQL

  1. #1
    Cognatuss avatar
    Jonas Magnusson
    Medlemsnr
    40573
    Ort
    Vänge, Uppsala
    Inlägg
    27

    Problematik datumsökning MySQL

    Jag håller på med ett databasbygge för webben och jobbar i PHP och MySQL.

    Jag har ställts inför ett litet problem som jag har svårt att komma runt med mina kraftigt begränsade programmeringskunskaper.

    Databasen är uppbyggd av ett stort antal tabeller som motsvarare en avskriven volym och typ av längd. Av dessa skapar jag sedan anpassade vyer (views) för att applicera mina queries på.

    Nu håller jag på och gör sökfunktion för data hämtade ur födelseböcker. Problemet jag har hänger ihop med att dessa födslar kan innehålla två olika datum, födelsedatum och dopdatum. Ibland är det båda, ibland endera och ibland inget.

    Jag försöker nu skapa en datumsortering av dessa poster, vilket inte är lätt.

    Skulle jag välja att sortera på endera av datumkolumnerna kommer alla som inte har ett angivet datum i den kolumnen att sorteras först eftersom de får datumet 0000-00-00. Därför har jag försökt skapa en ny, tredje datumkolumn, enbart som sorteringshjälp. Tanken är att först och främst skall sorteringskolumnen i viewn innehålla födelsedatum om det finns, sen dopdatum och slutligen 0000-00-00 om inget av dem finns.

    Till detta har jag försökt använda COALESCE vilket returnerar det första värdet som inte är NULL:

    Kod:
    COALESCE(FDatum, DDatum, "0000-00-00") AS Date
    Men det fungerar inte eftersom "0000-00-00" inte tolkas som ett datum och därför ändras typen på fältet från DATE till någon variant av CHAR. Då tappar jag funktionaliteten av datumtypen. Detta skulle man väl kunna komma runt genom att skapa en dummy-kolumn i varje tabell där alla poster får datumet 0000-00-00 och byta ut det i koden ovan, men det känns som en konstig omväg!?

    Ett annat problem är att för att kunna använda COALESCE enligt ovan måste jag ersätta alla tomma rutor i databasen med NULL, vilket får till följd att när jag försöker skapa en sql-fråga i PHP så hittar sökningen inte någon post som har ett NULL i endera datumkolumnen.

    Jag tycker att sqlfrågan borde vara utformad typ så här:

    Kod:
    $sql = mysql_query("SELECT * FROM vy WHERE 
         FDatum LIKE '$FDatum%'
         AND DDatum LIKE '$DDatum%'
         AND X LIKE '$X%'
         AND Y LIKE '$Y%'
         AND Z LIKE '$Z%'		
         o. s. v.
    Men det är något som inte fungerar med datumen?

    Hur löser jag den här problematiken?

    Ska man använda CASE i s f COALESCE och hur går det till?

    All hjälp mottages tacksamt!

    MVH

    Jonas
    Jonas Magnusson
    www.cognatus.se


  2. #2

    Tommy Petersson
    Medlemsnr
    49794
    Inlägg
    240
    Bara några funderingar:

    Kanske det inte går att använda år 0, pröva 1 jan år 1 istället.

    Istället för att i Coalesce ha tredje alternativet som en sträng, använd den via en CAST/CONVERT till Date.

  3. #3
    Phryxes avatar
    C-G Magnusson
    Medlemsnr
    13088
    Inlägg
    984
    Enligt manualen till MySQL 5.6 och DATE ... "The supported range is '1000-01-01' to '9999-12-31'. "

  4. #4

    Tommy Petersson
    Medlemsnr
    49794
    Inlägg
    240
    Det var ju lite ynkligt för vikingsläktforskning... ;-)

  5. #5
    Phryxes avatar
    C-G Magnusson
    Medlemsnr
    13088
    Inlägg
    984
    Är inte säker på vad du vill åstadkomma, men du kanske kan ha nytta av IF* i din SELECT-sats om du vill sortera på FDatum eller DDatum.

    * eller CASE

  6. #6
    Cognatuss avatar
    Jonas Magnusson
    Medlemsnr
    40573
    Ort
    Vänge, Uppsala
    Inlägg
    27
    Ett försök att visualisera det jag vill åstadkomma.

    Jag har flera tabeller:

    Tabell 1

    Kod:
    FDATUM---------DDATUM---------NAMN
    1650-02-02-----1650-02-05-----Jon
    ---------------1650-03-01-----Brita
    1650-04-12-----1650-04-14-----Olof
    1650-05-11--------------------Erik
    Tabell 2

    Kod:
    FDATUM---------DDATUM---------NAMN
    ------------------------------Lisken
    1650-02-01-----1650-02-04-----Hans
    ---------------1650-04-02-----Lars
    1650-05-12-----1650-05-14-----Karl
    Det jag vill åstadkomma är en vy som har ytterligare en datumkolumn som jag kan sortera på:

    Vy
    Kod:
    SDATUM---------FDATUM---------DDATUM---------NAMN
    1000-01-01-----------------------------------Lisken
    1650-02-01-----1650-02-01-----1650-02-04-----Hans
    1650-02-02-----1650-02-02-----1650-02-05-----Jon
    1650-03-01--------------------1650-03-01-----Brita
    1650-04-02--------------------1650-04-02-----Lars
    1650-04-12-----1650-04-12-----1650-04-14-----Olof
    1650-05-11-----1650-05-11--------------------Erik
    1650-05-12-----1650-05-12-----1650-05-14-----Karl

    Jag har som jag nämnde här ovan testat detta, men det blir inte bra:
    Kod:
    CREATE 
    SQL SECURITY INVOKER VIEW vy
    AS
    SELECT COALESCE(FDatum, DDatum,"1000-01-01") AS SDatum, FDatum, DDatum
    FROM Tabell1
    UNION
    SELECT COALESCE(FDatum, DDatum,"1000-01-01") AS SDatum, FDatum, DDatum
    FROM Tabell2

    Jag har testat lite nu med CAST/CONVERT och även STR_TO_DATE, men jag lyckas inte skapa någon vy. Jag har säkert fel i syntaxen så ett konkret exempel vore guld värt!

    Mvh Jonas
    Jonas Magnusson
    www.cognatus.se


  7. #7
    Phryxes avatar
    C-G Magnusson
    Medlemsnr
    13088
    Inlägg
    984
    Undrar om nåt sånt här kan fungera ... Orkar inte testa

    Kod:
    SELECT IF(FDatum<>NULL,FDatum,IF(DDatum<>NULL,DDatum,'1000-01-01')) as sdatum, fdatum, ddatum, namn
    FROM tabell
    ORDER BY sdatum, namn
    Om tomma datumfält är NULL, annars får du jämföra med default-värdet.
    Senast redigerad av Phryxe den 2013-03-13 klockan 16:58.

  8. #8

    Tommy Petersson
    Medlemsnr
    49794
    Inlägg
    240
    För att få fram SDatum blir det ju något typ:

    SELECT COALESCE(FDatum, DDatum,Convert(date,"1000-01-01")) AS SDatum
    FROM Tabell1

    Vill du också ha DDatum i samma SELECT lär det väl bli:
    SELECT COALESCE(FDatum, DDatum,Convert(date,"1000-01-01")) AS SDatum, COALESCE(DDatum,Convert(date,"1000-01-01")) AS DDatum
    FROM Tabell1

  9. #9
    Cognatuss avatar
    Jonas Magnusson
    Medlemsnr
    40573
    Ort
    Vänge, Uppsala
    Inlägg
    27
    Citat Ursprungligen postat av Phryxe Visa inlägg
    Undrar om nåt sånt här kan fungera ... Orkar inte testa

    Kod:
    SELECT IF(FDatum<>NULL,FDatum,IF(DDatum<>NULL,DDatum,'1000-01-01')) as sdatum, fdatum, ddatum, namn
    FROM tabell
    ORDER BY sdatum, namn
    Om tomma datumfält är NULL, annars får du jämföra med default-värdet.

    Tack för försöket men resultatet blir detsamma som när jag använder COALESCE.

    Poster där endera kolumnen innehåller NULL bli sorteringsdatumet 1000-01-01 oavsett om den andra kolumnen innehåller ett datum. Samt att den nya kolumnen SDatum blir av typen VARBINARY, vilket jag antar beror att "1000-01-01" är en textsträng.
    Jonas Magnusson
    www.cognatus.se


  10. #10
    Cognatuss avatar
    Jonas Magnusson
    Medlemsnr
    40573
    Ort
    Vänge, Uppsala
    Inlägg
    27
    Citat Ursprungligen postat av tommypeters Visa inlägg
    För att få fram SDatum blir det ju något typ:

    SELECT COALESCE(FDatum, DDatum,Convert(date,"1000-01-01")) AS SDatum
    FROM Tabell1
    MySQL köper inte den konverteringen, fel syntax #1064.
    Jonas Magnusson
    www.cognatus.se


  11. #11
    Phryxes avatar
    C-G Magnusson
    Medlemsnr
    13088
    Inlägg
    984
    "Om tomma datumfält är NULL, annars får du jämföra med default-värdet.".

    Defaultvärdet tycks vara '0000-00-00', inte NULL. Om du byter ut NULL mot '0000-00-00' i IF-satsen bör det funka.

  12. #12
    Cognatuss avatar
    Jonas Magnusson
    Medlemsnr
    40573
    Ort
    Vänge, Uppsala
    Inlägg
    27
    Citat Ursprungligen postat av Phryxe Visa inlägg
    "Om tomma datumfält är NULL, annars får du jämföra med default-värdet.".

    Defaultvärdet tycks vara '0000-00-00', inte NULL. Om du byter ut NULL mot '0000-00-00' i IF-satsen bör det funka.
    Tack, det funkar, men det måste innebära att om ett datumvärde i originaltabellen är satt till NULL, vilket alla som saknar värde är i mitt fall, så hanteras det som '0000-00-00'?

    Då är det bara problemet att den skapade sorteringskolumnen blir varbinary kvar?
    Jonas Magnusson
    www.cognatus.se


  13. #13
    Phryxes avatar
    C-G Magnusson
    Medlemsnr
    13088
    Inlägg
    984
    Jag testade att skapa en minimal tabell och om jag inte definierade ett standard-värde i ett DATE-fält så blev standardvärdet '0000-00-00'. Man kan definiera andra standardvärden, ex. NULL eller '1000-01-01' om man vill.

  14. #14
    Cognatuss avatar
    Jonas Magnusson
    Medlemsnr
    40573
    Ort
    Vänge, Uppsala
    Inlägg
    27
    Jag hade definierat standardvärdet till NULL i mina tabeller, men det hade uppenbarligen ingen funktion, för då borde ju din första variant ha funkat kan jag tycka!

    Men skitsamma, nu funkar det ju...
    Jonas Magnusson
    www.cognatus.se


  15. #15
    Phryxes avatar
    C-G Magnusson
    Medlemsnr
    13088
    Inlägg
    984
    Kanske så här ...

    Kod:
    SELECT CONVERT(IF(FDatum<>'0000-00-00',FDatum,IF(DDatum<>'0000-00-00',DDatum,'1000-01-01')),DATE) as sdatum, fdatum, ddatum, namn
    FROM tabell
    ORDER BY sdatum, namn

  16. #16
    Cognatuss avatar
    Jonas Magnusson
    Medlemsnr
    40573
    Ort
    Vänge, Uppsala
    Inlägg
    27
    Nope
    Jonas Magnusson
    www.cognatus.se


  17. #17
    Phryxes avatar
    C-G Magnusson
    Medlemsnr
    13088
    Inlägg
    984
    Är det fortfarande varbinary?

    Otillåtna värden tycks generera '0000-00-00' ...

  18. #18
    Cognatuss avatar
    Jonas Magnusson
    Medlemsnr
    40573
    Ort
    Vänge, Uppsala
    Inlägg
    27
    Citat Ursprungligen postat av Phryxe Visa inlägg
    Är det fortfarande varbinary?

    Otillåtna värden tycks generera '0000-00-00' ...
    Det senaste försöket blir en #1064 fel syntax.

    Utan någon CONVERT blir sökkolumnen varbinary.
    Jonas Magnusson
    www.cognatus.se


  19. #19
    Cognatuss avatar
    Jonas Magnusson
    Medlemsnr
    40573
    Ort
    Vänge, Uppsala
    Inlägg
    27
    Här beskrivs något liknande och han använder CAST.

    http://phe1129.wordpress.com/2011/01...umn-data-type/

    Men tyvärr inget exempel med datatypen DATE.
    Jonas Magnusson
    www.cognatus.se


  20. #20
    Cognatuss avatar
    Jonas Magnusson
    Medlemsnr
    40573
    Ort
    Vänge, Uppsala
    Inlägg
    27
    Jag har gjort en temporär lösning genom att lägga till en dummykolumn i originaltabellerna så att jag kan använda den i s f för textsträngen som krånglar till det:

    Kod:
    SELECT IF(FDatum<>'0000-00-00',FDatum,IF(DDatum<>'0000-00-00',DDatum,Dummy)) as sdatum, fdatum, ddatum, namn
    Det känns ju inte riktigt rätt, men det funkar!

    Kommer någon på hur man löser problemet är jag givetvis tacksam!
    Jonas Magnusson
    www.cognatus.se


+ Svara på ämne
Sidan 1 av 2 1 2 SistaSista

Behörigheter för att posta

  • Du får inte posta nya ämnen
  • Du får inte posta svar
  • Du får inte posta bifogade filer
  • Du får inte redigera dina inlägg