FAQ |
Kalender |
![]() |
#1 | |||
|
||||
Klarade millennium-buggen
|
Hmmm, har kliat skallen ett tag nu hur man gör en join på två datetime fält i MSSQL (Transact SQL). Problemet är givetvis tidsdelen av datumet som skiljer sig åt. Går det att klippa bort tiden när man gör denna join?
Kod:
Tabell1: datum * * * * * * * * * * * * * * * * * * text1 -------------------------------------------- 2005-01-01 10:02:34 * * * * * * bla 2005-01-02 00:00:12 * * * * * * blabla * ** * <---join blir fel pga tiden 2005-01-06 12:33:20 * * * * * * blablabla Tabell2: datum * * * * * * * * * * * * * * * * * * text2 -------------------------------------------- 2004-12-01 10:02:34 * * * * * * hehehe 2005-01-02 04:32:32 * * * * * * hehe * * * <---join blir fel pga tiden 2005-01-03 10:02:34 * * * * * * he vill ha det till: datum * * * * * * * * * * * * * * * * * * text1 * * * * * *text2 ------------------------------------------------------------------- 2004-12-01 * * * * * * NULL * * * * * * hehehe 2005-01-01 * * * * * * bla * * * * * * * * NULL 2005-01-02 * * * * * * blabla * * * * * *hehe 2005-01-03 * * * * * * NULL * * * * * * *he 2005-01-06 * * * * * * blablabla * * * *NULL |
|||
![]() |
![]() |
![]() |
#2 | ||
|
|||
Mycket flitig postare
|
Datum lagras oftast i form av flyttal där dagen bestäms av heltalsdelen och tiden av decimal-delen. Mig veterligen finns det ingen funktion för att trunkera datum till att enbart gå på heltalet, men en alternativ lösning som du kanske kan testa är ju att lägga in att den jämför om datumet ligger inom intervallet kl 00.00:00-23.59:59 under ett visst dygn. Om detta går att tillämpa i just en join-sats är jag dock osäker på.
|
||
![]() |
![]() |
![]() |
#3 | |||
|
||||
Klarade millennium-buggen
|
Jag har testat att efter min select göra om datumet till en char med endast 10 tecken (går på andra sätt också), exemeplvis:
Kod:
SELECT T1.*, T2.*, convert(char(10), T1.datum, 102) as datum1, convert(char(10), T2.datum, 102) as datum2 FROM Tabell1 T1 JOIN Tabell2 T2 ON datum1 = datum2 WHERE ...etc...etc men det fungerar ju inte... |
|||
![]() |
![]() |
![]() |
#4 | ||
|
|||
Mycket flitig postare
|
om du istället för:
tabell1.datum resp tabell2.datum skriver: covert(char(10),tabell1.datum,120) resp covert(char(10),tabell2.datum,120) så kommer du bara jämföra datum som är identiska. Fast om det är så att datat pga buggig inläggning (dvs den lägger in med tid trots att det är bara datumet som är intressant) så bör du kika på inläggningen istället så du slipper converta i selecten. De poster som redan finns kan ju i så fall enkelt uppdateras med en convert. |
||
![]() |
![]() |
![]() |
#5 | ||
|
|||
Mycket flitig postare
|
Ser att du kom på lösningen själv...
Det jag tror du gör fel nu är att du inte gör en outer join. Det "som inte funkar" är att dina rader med "null" (för att datumen finns i en tabell men inte den andra) saknas. korrekt? |
||
![]() |
![]() |
![]() |
#6 | |||
|
||||
Klarade millennium-buggen
|
Nja, min lösning fungerar ju inte riktigt.
Jag kan inte joina på datum1 och datum2 då får jag ett fel: invalid columnname 'datum1' (respektive 'datum2') Och det ska vara JOIN, dvs om jag har förstått JOIN'ar rätt. Jag har liksom flera tabeller med loggdata som ska paketeras ihop på "bredden" dvs data ifrån flera olika loggar ska skrivas in i olika fält på samma rad i recordset'et. En inner/outer/left join exkluderar ju åt endera hållet, här ska det vara villkorslöst. Ingen logg bestämmer om en annan logg ska finnas med mao. Och jag måste ha med tid i fältet för dessa tabeller används i andra sammanhang där tidsstämpel är viktig... |
|||
![]() |
![]() |
![]() |
#7 | ||
|
|||
Mycket flitig postare
|
Funkar inte?
Kod:
SELECT T1.*, T2.* FROM Tabell1 T1 JOIN Tabell2 T2 ON convert(char(10), T1.datum, 102) = convert(char(10), T2.datum, 102) WHERE ...etc...etc left/outer joins är ett måste om du vill ha "null där värde saknas", således måste du låte en tabell styra över den andra. Om du verkligen inte har någon tabell som styr så får du nog köra en union enligt principen: Välj alla som har matchning UNION alla som bara finns i T1 UNION alla som bara finns i T2. Kod:
select T1.*, T2.* FROM T1, T2 WHERE convert(char(10), T1.datum, 102) = convert(char(10), T2.datum, 102) UNION select T1.*, T2.* FROM T1, T2 WHERE convert(char(10), T1.datum, 102) =* convert(char(10), T2.datum, 102) AND convert(char(10), T2.datum, 102) not in (select convert(char(10), T2.datum, 102) FROM T1, T2 WHERE convert(char(10), T1.datum, 102) = convert(char(10), T2.datum, 102)) UNION select T1.*, T2.* FROM T1, T2 WHERE convert(char(10), T1.datum, 102) *= convert(char(10), T2.datum, 102) AND convert(char(10), T1.datum, 102) not in (select convert(char(10), T1.datum, 102) FROM T1, T2 WHERE convert(char(10), T1.datum, 102) = convert(char(10), T2.datum, 102)) |
||
![]() |
![]() |
![]() |
#8 | |||
|
||||
Klarade millennium-buggen
|
Tack, ego.
Det blev en variant på dina UNION's som löste det. Kan inte mixtra så mycket med recordset'et pga den lösning jag har valt (jag skjuter in resultatet rakt in i en kontroll (asp.net vettu...) Jag får bjuda på en virtuell öl som tack för hjälpen. B) |
|||
![]() |
![]() |
![]() |
#9 | ||
|
|||
Mycket flitig postare
|
Citat:
|
||
![]() |
![]() |
Svara |
|
|