Kom ihåg mig?
Home Menu

Menu


JOIN på date

Ämnesverktyg Visningsalternativ
Oläst 2005-01-07, 23:17 #1
Roberts avatar
Robert Robert är inte uppkopplad
Klarade millennium-buggen
 
Reg.datum: Jan 2004
Inlägg: 2 103
Robert Robert är inte uppkopplad
Klarade millennium-buggen
Roberts avatar
 
Reg.datum: Jan 2004
Inlägg: 2 103
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
Robert är inte uppkopplad   Svara med citatSvara med citat
Oläst 2005-01-07, 23:41 #2
Lindahl Lindahl är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Dec 2004
Inlägg: 854
Lindahl Lindahl är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Dec 2004
Inlägg: 854
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å.
Lindahl är inte uppkopplad   Svara med citatSvara med citat
Oläst 2005-01-08, 00:10 #3
Roberts avatar
Robert Robert är inte uppkopplad
Klarade millennium-buggen
 
Reg.datum: Jan 2004
Inlägg: 2 103
Robert Robert är inte uppkopplad
Klarade millennium-buggen
Roberts avatar
 
Reg.datum: Jan 2004
Inlägg: 2 103
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...
Robert är inte uppkopplad   Svara med citatSvara med citat
Oläst 2005-01-08, 00:11 #4
eg0master eg0master är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Oct 2004
Inlägg: 898
eg0master eg0master är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Oct 2004
Inlägg: 898
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.
eg0master är inte uppkopplad   Svara med citatSvara med citat
Oläst 2005-01-08, 00:14 #5
eg0master eg0master är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Oct 2004
Inlägg: 898
eg0master eg0master är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Oct 2004
Inlägg: 898
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?
eg0master är inte uppkopplad   Svara med citatSvara med citat
Oläst 2005-01-08, 13:14 #6
Roberts avatar
Robert Robert är inte uppkopplad
Klarade millennium-buggen
 
Reg.datum: Jan 2004
Inlägg: 2 103
Robert Robert är inte uppkopplad
Klarade millennium-buggen
Roberts avatar
 
Reg.datum: Jan 2004
Inlägg: 2 103
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...
Robert är inte uppkopplad   Svara med citatSvara med citat
Oläst 2005-01-08, 14:46 #7
eg0master eg0master är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Oct 2004
Inlägg: 898
eg0master eg0master är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Oct 2004
Inlägg: 898
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
och alltså en join som du gör kommer begränsa resultatet till bara de rader där T1.datum=T2.datum existerar.

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))
Något i den stilen borde göra jobbet, men frågan är om det inte är enklare (nu när du saknar "styrtabell") plocka ut resultat för resultat loopa igenom datumen manuellt och skapa den output du vill ha. Ett alternativ till UNION är ju så klart att lägga resultetaten i en temptabell och bygga upp det färdiga resultetatet den vägen, lämpligen i en SP.
eg0master är inte uppkopplad   Svara med citatSvara med citat
Oläst 2005-01-09, 21:00 #8
Roberts avatar
Robert Robert är inte uppkopplad
Klarade millennium-buggen
 
Reg.datum: Jan 2004
Inlägg: 2 103
Robert Robert är inte uppkopplad
Klarade millennium-buggen
Roberts avatar
 
Reg.datum: Jan 2004
Inlägg: 2 103
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)
Robert är inte uppkopplad   Svara med citatSvara med citat
Oläst 2005-01-09, 21:14 #9
eg0master eg0master är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Oct 2004
Inlägg: 898
eg0master eg0master är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Oct 2004
Inlägg: 898
Citat:
Originally posted by Robert@Jan 9 2005, 22:00
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)
jag menade inte att du skulle mixtra med datasetet utan att du i en SP (Stored Procedure) skulle skapa en temptabell med ditt önskade utseende och sedan fylla temptabellen bit för bit (istf en gigantisk union) och sedan göra select * från din temptabell.
eg0master är inte uppkopplad   Svara med citatSvara med citat
Svara


Aktiva användare som för närvarande tittar på det här ämnet: 1 (0 medlemmar och 1 gäster)
 

Regler 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

BB-kod är
Smilies är
[IMG]-kod är
HTML-kod är av

Forumhopp


Alla tider är GMT +2. Klockan är nu 17:03.

Programvara från: vBulletin® Version 3.8.2
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Svensk översättning av: Anders Pettersson
 
Copyright © 2017