Avatar billede henrik2000 Nybegynder
16. maj 2002 - 08:41 Der er 43 kommentarer og
3 løsninger

datosammenligning

Hej!

jeg har 2 tabeller hvor jeg prøver at finde alle datoer fra tabel1 som er forskellig fra de datoer som findes i tabel2. Tabel1`s datofelt har typen "smalldatetime", og tabel2`s datofelt har typen "datetime".
(det kan der ikke laves om på)
-------------------------------------------------
SELECT tabel1.*, ISNULL(tabel2.Dato, '')
    AS DatoFindesIkke
FROM tabel1 LEFT OUTER JOIN
    tabel2 ON tabel1.Dato = tabel2.Dato
-------------------------------------------------
Resultatet af ovenstående select bliver at DatoFindesIkke bliver "01-01-1900", så der er noget jeg mangler.

Nogen forslag?

Avatar billede bennytordrup Nybegynder
16. maj 2002 - 08:46 #1
select tabel1.*, case when tabel2.dato is null then '<null>' else tabel2.dato end as datofindesikke
from tabel1 left outer join tabel2 on tabel1.dato = tabel2.dato
Avatar billede henrik2000 Nybegynder
16. maj 2002 - 09:03 #2
Når jeg kører den i query analyzer får jeg besked om at case ikke er supporteret. Den finder desuden kun 1 dato fra tabellen, og der er flere forskellige...
Avatar billede bennytordrup Nybegynder
16. maj 2002 - 09:04 #3
select @@version
Avatar billede henrik2000 Nybegynder
16. maj 2002 - 09:06 #4
jeg har SQL Server 7.0...
Avatar billede bennytordrup Nybegynder
16. maj 2002 - 09:08 #5
Og jeg har 2000

Jeg mente ellers ikke, at case var nyt for 2000.
Avatar billede henrik2000 Nybegynder
16. maj 2002 - 09:09 #6
Andre forslag?
Avatar billede bennytordrup Nybegynder
16. maj 2002 - 09:11 #7
Nej, for problemet er, at SQL Serveren forsøger at konvertere den tomme streng ('') til en dato, og det giver 01-01-1900.
Avatar billede bennytordrup Nybegynder
16. maj 2002 - 09:12 #8
Med en case kunne der evt castes til en varchar.
Avatar billede hansk Nybegynder
16. maj 2002 - 09:13 #9
Du kan formentlig ikke joine 2 felter med forskellig definition og forvente et brugbart resultat.
I stedet kan du konvertere felterne til noget sammenligneligt:
SELECT tabel1.* FROM Tabel1 WHERE Format$(tabel1.dato, "yyyymmdd") NOT IN (SELECT Format$(tabel2.dato, "yyyymmdd") FROM tabel2)
Jeg går her ud fra at MSSQL kan håndtere er FORMAT.
Avatar billede henrik2000 Nybegynder
16. maj 2002 - 09:13 #10
Ja, men kan man ikke løse problemet med den tomme streng på en eller anden måde???
Avatar billede bennytordrup Nybegynder
16. maj 2002 - 09:15 #11
select tabel1.*, case when tabel2.dato is null then '<null>' else cast(tabel2.dato as varchar) end as datofindesikke

Jeg har lige prøvet på en SQL 7. case er supporteret.
Avatar billede bennytordrup Nybegynder
16. maj 2002 - 09:16 #12
hansk> format understøttes ikke af MSSQL
Avatar billede hansk Nybegynder
16. maj 2002 - 09:21 #13
Okay, hvis format ikke understøttes, så prøv uden:
SELECT tabel1.* FROM Tabel1 WHERE tabel1.dato NOT IN (SELECT tabel2.dato FROM tabel2)
Avatar billede bennytordrup Nybegynder
16. maj 2002 - 09:22 #14
hansk > det vil give de poster, som ikke findes i tabel2. Du vil ikke få de poster i tabel1, hvor datoen findes i tabel2.
Avatar billede hansk Nybegynder
16. maj 2002 - 09:26 #15
benny> det var vel også spørgsmålet.
Avatar billede bennytordrup Nybegynder
16. maj 2002 - 09:28 #16
hansk>den oprindelige forespørgsel brugte en left join mellem tabel1 og tabel2. Der blev ikke fravalgt de poster, hvor tabel2.dato var null. Derfor svarer din forespørgsel ikke til den oprindelige.
Avatar billede bennytordrup Nybegynder
16. maj 2002 - 09:32 #17
Alternativt:

SELECT tabel1.*
FROM Tabel1
WHERE tabel1.dato NOT IN (SELECT tabel2.dato FROM tabel2)

union
SELECT tabel1.*
FROM Tabel1
WHERE tabel1.dato IN (SELECT tabel2.dato FROM tabel2)
Avatar billede hansk Nybegynder
16. maj 2002 - 09:32 #18
Det er korrekt, men jeg prøver at forholde mig til det der rent faktisk bliver spurgt om. Måske vil Henrik uddybe lidt?
Avatar billede henrik2000 Nybegynder
16. maj 2002 - 09:33 #19
Jeg vil bare gerne skrive response.write "dato findes ikke" hvis der er en
dato i tabel1 der ikke findes i tabel2...

Hvad med CONVERT?

SELECT tabel1.*, CONVERT(Datetime, Dato, 102)
FROM tabel1
WHERE (CONVERT(Datetime, Dato, 102) NOT IN
        (SELECT tabel2.dato
      FROM tabel2))
Avatar billede bennytordrup Nybegynder
16. maj 2002 - 09:33 #20
Brug 112 i stedet for 102
Avatar billede bennytordrup Nybegynder
16. maj 2002 - 09:34 #21
Vil du vise poster fra tabel1, hvis den findes i tabel2?
Avatar billede henrik2000 Nybegynder
16. maj 2002 - 09:35 #22
Nej, som jeg skrev, finde alle datoer i tabel1 der IKKE findes i tabel2.
Avatar billede bennytordrup Nybegynder
16. maj 2002 - 09:41 #23
OK, men du bruge en left outer join uden at have en Where tabel2.dato IS Null.

Det ville give dig poster fra tabel1 også, hvis de havde en matchende dato i tabel2.

SELECT tabel1.*, 'Dato i tabel2 findes ikke' as FeltTilResponseWrite
FROM Tabel1
WHERE tabel1.dato NOT IN (SELECT tabel2.dato FROM tabel2)
Avatar billede hansk Nybegynder
16. maj 2002 - 10:03 #24
henrik> har du prøvet mit forslag fra 16/05-2002 09:21:28 ???
Avatar billede henrik2000 Nybegynder
16. maj 2002 - 10:11 #25
Jeg har prøvet alle forslag, men jeg syntes der mangler noget...

på min asp-side prøver jeg så at skrive

sqlstr = "SELECT tabel1.* FROM Tabel1 WHERE tabel1.dato NOT IN (SELECT tabel2.dato FROM tabel2)"
set rs = conn.Execute(sqlstr)
If rs.eof = true then
Response.Write "Dato findes ikke"
else
Response.Write "dato findes"
end if
               
er det måden at gøre det på?
Avatar billede hansk Nybegynder
16. maj 2002 - 10:16 #26
Du må regne med at få mange rækker som svar.
For hver række du får vil der mangle en dato i tabel2.
Avatar billede hansk Nybegynder
16. maj 2002 - 10:17 #27
Derfor skal du starte i begyndelsen af dit recordset og flytte dig nedad med en rs.movenext. Så kan du teste hver enkelt svar du får.
Avatar billede henrik2000 Nybegynder
16. maj 2002 - 10:19 #28
hvis der nu er 6 rækker i tabel1, hvoraf 2 af rækkerne har en dato der ikke findes i tabel2, men tabel2 indeholder 300 rækker, hvordan får jeg den så til at skrive
"findes ikke" 2 gange og "findes" 4 gange?
Avatar billede henrik2000 Nybegynder
16. maj 2002 - 10:20 #29
hvis jeg gør sådan her:
Do while not rs.eof
Response.Write rs("dato") & "<br>"
rs.movenext
loop
- får jeg også mange rækker ud...
Avatar billede hansk Nybegynder
16. maj 2002 - 10:22 #30
Med den sql du først spurgte om får du kun at vide at der ikke findes 2 rækker.

Eks:
rs.bof
If rs.eof then
Response.Write "Ikke flere records"
else
Response.Write "dato findes ikke i tabel2"
end if
end if
Avatar billede hansk Nybegynder
16. maj 2002 - 10:27 #31
hvis du vil have alle rækker fra tabel1 testet skal din sql se sådan ud:

SELECT tabel1.*, tabel2.Dato FROM tabel1 LEFT OUTER JOIN
    tabel2 ON tabel1.Dato = tabel2.Dato

Derefter kan du teste for null værdi i tabel2.Dato.
Avatar billede hansk Nybegynder
16. maj 2002 - 10:32 #32
Din "do while" løkke vil fungere fint, sæt den sammen med en test af værdierne i dato feltet og så er du kørende.
Avatar billede henrik2000 Nybegynder
16. maj 2002 - 10:32 #33
Altså således:
SELECT tabel1.*
FROM tabel1 LEFT OUTER JOIN
    tabel2 ON tabel1.Dato = tabel2.Dato AND
    tabel1.id = tabel2.id AND tabel2.dato IS Null
WHERE (CONVERT(Datetime, Dato, 102) NOT IN
        (SELECT tabel2.dato
      FROM tabel2))
(jeg skal også lige have et ID med...)

Og hvordan så med asp? vil jeg ikke stadig få skrevet mange rækker ud???
Avatar billede hansk Nybegynder
16. maj 2002 - 10:43 #34
SELECT tabel1.*, tabel2.dato
FROM tabel1 LEFT OUTER JOIN
    tabel2 ON tabel1.Dato = tabel2.Dato AND
    tabel1.id = tabel2.id

På denne måde vil ens datoer vise sig ved at tabel2.dato har en valid værdi og manglende datoer vise sig ved at tabel2.dato har en null værdi.
Brug denne sammen med din do-while løkke og så er din lykke gjort.
Avatar billede henrik2000 Nybegynder
16. maj 2002 - 10:58 #35
i min query analyzer siger den 30 rows, men hvis jeg laver

Do while not rs.eof
Response.Write "dato findes ikke"
rs.movenext
loop

skriver den "dato findes ikke" 30 x 6 gange (der er 6 rækker med ID)
Avatar billede terry Ekspert
16. maj 2002 - 11:04 #36
Try
WHERE NOT EXISTS
Avatar billede henrik2000 Nybegynder
16. maj 2002 - 11:07 #37
hvordan bruger man where not exists?
Avatar billede hansk Nybegynder
16. maj 2002 - 11:11 #38
Mener du 30 x 6 = 180 gange?
Avatar billede henrik2000 Nybegynder
16. maj 2002 - 11:13 #39
ja - den må loope for alle 6 ID`er og så skrive det 30 gange for hver dato der ikke findes...
Avatar billede terry Ekspert
16. maj 2002 - 11:20 #40
SELECT * FROM tabel1 T1
WHERE NOT EXISTS (SELECT 1 FROM tabel2 T2
WHERE  T1.Dato = T2.Dato

but I think your still going to have problems as the date field DO NOT contain the same date format
Avatar billede hansk Nybegynder
16. maj 2002 - 11:23 #41
Prøv at udelade datoen i dit join og så simpelthen test for værdien i tabel2.dato:

SELECT tabel1.*, tabel2.dato
FROM tabel1 LEFT OUTER JOIN 
            tabel1.id = tabel2.id
Avatar billede terry Ekspert
16. maj 2002 - 11:25 #42
You could use CONVERT but it will mean having to CONVERT to the small datetime format

SELECT * FROM tabel1 T1
WHERE NOT EXISTS (SELECT 1 FROM tabel2 T2
WHERE  CONVERT(datetime, T1.Dato, 112) = CONVERT(datetime, T2.Dato, 112)
Avatar billede terry Ekspert
16. maj 2002 - 11:26 #43
112 = YYYYMMDD
Avatar billede henrik2000 Nybegynder
16. maj 2002 - 11:27 #44
Nu fandt jeg løsningen (efter et kig i hjælpen i sql server):

CONVERT gav problemer, men CAST virker bedre:

SELECT tabel1.*, ISNULL(CAST(tabel2.Dato as varchar(30)),'')
    AS bInvalidDate
FROM tabel1 LEFT OUTER JOIN
    tabel2 ON tabel1.Dato = tabel2.Dato AND
    tabel1.id = tabel2.id
Avatar billede henrik2000 Nybegynder
16. maj 2002 - 11:29 #45
I får alle point - mange tak for hjælpen!
Avatar billede terry Ekspert
16. maj 2002 - 11:38 #46
selv tak :o)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester