Excel Forum - Porady, Pomoc,  Excel Help, Excel FAQ Strona Główna
 FAQ  RegulaminRegulamin  Szukaj   Użytkownicy   Grupy   Rejestracja   Profil   Twoje wiadomości   Zaloguj 


Poprzedni temat «» Następny temat
ID tematu: 63073 Skopiuj do schowka Porównywanie tabel SQL
Autor Wiadomość
jaholden 
Starszy Forumowicz


Pomógł: 1 raz
Posty: 59
Wysłany: 06-11-2018, 11:38   Porównywanie tabel SQL

Hej Hej!

Mam problem z utowrzeniem prawidłowej kwerendy SQL w skrypcie pliku VBS.
Chodzi o to, że powinna porównać dwie tabele (każda w osobnym pliku) i wyrzucić tylko te rekordy które znajdują się w jednym pliku ale w drugim nie występują.

TABELA1.csv
Kod:
kolumna_1 | kolumna_2 | kolumna_3
ala       | ma        | kota
szybcy    | i         | wscielki
duzo      | tanio     | tesco
zycie     | mi        | zmarnowales


TABELA2.csv
Kod:
kolumna_1 | kolumna_2 | kolumna_3
ala       | kota      | ma
szybcy    | i         | wscielki
duzo      | tanio     | tesco
zycie     | mi        | uratowales


Wynikiem powinno być oczywiście:
Kod:
ala       | kota      | ma
zycie     | mi        | uratowales

Czy ma ktoś pomysł jak napisać taką kwerendę (zmienna "kwerenda") do porównywania między plikami/tabelami?


Tak wygląda mój kod (również w załączniku w pliku txt

Kod:


Dim fso,shell
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set shell = CreateObject("WScript.Shell")
    If Instr(WScript.FullName, "\System32\") And fso.FolderExists("C:\Windows\SysWow64") Then
        shell.Run "C:\Windows\SysWow64\wScript.exe  """ & wscript.scriptFullName & """"
        Wscript.quit
    End If

    Dim polacz   
    Const adOpenStakwerenda = 3
    Const adLockOptimiskwerenda = 3
    Const adCmdText = &H0001
    Dim fullPath
    fullPath = fso.GetParentFolderName(fso.GetFile(Wscript.ScriptFullName))
   
    Set objExcel = CreateObject("Excel.Application")
    objExcel.Visible = False
    objExcel.DisplayAlerts = False

    Set polacz = CreateObject("ADODB.Connection")
    polacz.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & "Data Source=" & fullPath & ";" & "Extended Properties=""text;HDR=YES;FMT=Delimited"""   
           
    Set rekord = CreateObject("ADODB.Recordset")
           
    Dim TABELA1, TABELA2

    TABELA1 = fullPath & "\TABELA1.csv"
    TABELA2 = fullPath & "\TABELA2.csv"
   
'<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
'<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
    kwerenda = "SELECT * FROM " & TABELA1 & " WHERE kolumna1 NOT LIKE 'szybcy'"
'<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
'<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>

    rekord.Open kwerenda, polacz, adOpenStakwerenda, adLockOptimiskwerenda, adCmdText

    Set OutputFile = fso.CreateTextFile(fullPath & "\wynik.js")

    i=0   

    Do Until rekord.eof
        OutputFile.WriteLine("kwerenda[" & i & "]={" & chr(34) & "znaleziony rekord" & chr(34) & ":" & chr(34) & rekord.fields.item("kolumna_1") & chr(34) & "};")
        i=i+1
        rekord.movenext   
    Loop

    rekord.Close
    OutputFile.Close
   
    objExcel.Quit


plik.txt
Pobierz Plik ściągnięto 31 raz(y) 1.78 KB

TABELA1.csv
Pobierz Plik ściągnięto 33 raz(y) 102 Bajtów

TABELA2.csv
Pobierz Plik ściągnięto 32 raz(y) 103 Bajtów

Ostatnio zmieniony przez jaholden 06-11-2018, 12:01, w całości zmieniany 1 raz  
ID posta: 355732 Skopiuj do schowka
 
 
kulasart
[Usunięty]

Wysłany: 06-11-2018, 11:43   

jaholden napisał/a:
wyrzucić tylko te rekordy które znajdują się w jednym pliku ale w drugim nie występują.

jaholden napisał/a:
Wynikiem powinno być oczywiście:
Kod:

szybcy    | i         | wscielki
duzo      | tanio     | tesco

Zdajesz sobię sprawę że wyniki jakie pokazałeś że są niby "oczywiste" nie wpisują się w to co opisałeś?

Podaj raz jeszcze, bardzo dokładnie co chcesz zrobić, oraz jakiego wyniku oczekujesz.
ID posta: 355735 Skopiuj do schowka
 
 
jaholden 
Starszy Forumowicz


Pomógł: 1 raz
Posty: 59
Wysłany: 06-11-2018, 12:02   

Masz rację! Podałem wynik odwrotny do oczekiwanego. Już poprawiłem swój post.
Dzięki za czujność :)
ID posta: 355737 Skopiuj do schowka
 
 
kulasart
[Usunięty]

Wysłany: 06-11-2018, 12:20   

Taka konstrukcja zapytania powinna dać oczekiwany przez Ciebie rezultat:
Kod:
select
    *
from tabela_1
where not exists (
    select 1
    from tabela_2
    where
        tabela_1.kolumna_1 = tabela_2.kolumna_1
        and tabela_1.kolumna_2 = tabela_2.kolumna_2
        and tabela_1.kolumna_3 = tabela_2.kolumna_3
)

union all

select
    tabela_2.*
from tabela_2
where not exists (
    select 1
    from tabela_1
    where
        tabela_1.kolumna_1 = tabela_2.kolumna_1
        and tabela_1.kolumna_2 = tabela_2.kolumna_2
        and tabela_1.kolumna_3 = tabela_2.kolumna_3
)
ID posta: 355740 Skopiuj do schowka
 
 
jaholden 
Starszy Forumowicz


Pomógł: 1 raz
Posty: 59
Wysłany: 06-11-2018, 12:53   

Wygląda fajnie :) Ale skrypt nie chce mi tego przyjąć, twierdząc po wywołaniu, że:

screen errora w zalaczniku

Kod:
kwerenda = "select * from " & TABELA1 & " where not exists ( select 1 from " & TABELA2 & " where " & TABELA1 & ".kolumna_1 = " & TABELA2 & ".kolumna_1 and " & TABELA1 & ".kolumna_2 = " & TABELA2 & ".kolumna_2 and " & TABELA1 & ".kolumna_3 = " & TABELA2 & ".kolumna_3) union all select " & TABELA2 & ".* from " & TABELA2 & " where not exists ( select 1 from " & TABELA1 & " where " & TABELA1 & ".kolumna_1 = " & TABELA2 & ".kolumna_1 and " & TABELA1 & ".kolumna_2 = " & TABELA2 & ".kolumna_2 and " & TABELA1 & " .kolumna_3 = " & TABELA2 & ".kolumna_3)"
[img]C:\Users\pjaskols\Desktop\err.png[/img]

err.png
Plik ściągnięto 921 raz(y) 11.1 KB

ID posta: 355749 Skopiuj do schowka
 
 
kulasart
[Usunięty]

Wysłany: 06-11-2018, 13:28   

Dlaczego używasz pełnych ścieżek do plików?
Skoro w połączeniu otwierasz folder, to wystarczy sama nazwa pliku.

U mnie w excelu takie coś działa:
Kod:
Sub TestQuery()
    Const adOpenStakwerenda = 3
    Const adLockOptimiskwerenda = 3
    Const adCmdText = &H1

   
    Dim connection As Object
    Set connection = CreateObject("ADODB.Connection")
   
    Dim directoryPath As String
    directoryPath = "C:\Users\lnow\Downloads"
   
    Dim connectionString As String
    If Val(Application.Version) < 12 Then
    connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
            "Data Source=" & directoryPath & ";" & _
            "Extended Properties=""text;HDR=YES;FMT=Delimited"""
    Else
    connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
            "Data Source=" & directoryPath & ";" & _
            "Extended Properties=""text;HDR=YES;FMT=Delimited"""
    End If
   
    connection.Open connectionString
   
    Dim rs As Object
    Set rs = CreateObject("ADODB.Recordset")
   
   
    Dim query As String
    query = "select kolumna_1, kolumna_2, kolumna_3 from TABELA1.csv tabela_1 where not exists (select 1 from TABELA2.csv tabela_2 where tabela_1.kolumna_1 = tabela_2.kolumna_1 and tabela_1.kolumna_2 = tabela_2.kolumna_2 and tabela_1.kolumna_3 = tabela_2.kolumna_3)" & _
        " union all " & _
        "select kolumna_1, kolumna_2, kolumna_3 from TABELA2.csv tabela_2 where not exists (select 1 from TABELA1.csv tabela_1 where tabela_1.kolumna_1 = tabela_2.kolumna_1 and tabela_1.kolumna_2 = tabela_2.kolumna_2 and tabela_1.kolumna_3 = tabela_2.kolumna_3)"

       
   
    rs.Open query, connection, adOpenStakwerenda, adLockOptimiskwerenda, adCmdText
End Sub
ID posta: 355758 Skopiuj do schowka
 
 
jaholden 
Starszy Forumowicz


Pomógł: 1 raz
Posty: 59
Wysłany: 06-11-2018, 13:38   

Dzięki za ten kod, zmodyfikowałem u siebie i teraz przyjmuje.

A jakie wyniki otrzymujesz? U mnie wypluło:
Kod:
kwerenda[0]={"znaleziony rekord":"zycie","mi","uratowales"};
kwerenda[1]={"znaleziony rekord":"zycie","mi","zmarnowales"};


Czyli po ostatnim rekordzie z obu tabel, zamiast:
Kod:
kwerenda[0]={"znaleziony rekord":"ala","kota","ma"};
kwerenda[1]={"znaleziony rekord":"zycie","mi","uratowales"};
ID posta: 355759 Skopiuj do schowka
 
 
kulasart
[Usunięty]

Wysłany: 06-11-2018, 13:47   

jaholden, zobacz dokładnie jakie dane masz w plikach.
Wynik jaki otrzymałeś jest w 100% prawidłowy.
ID posta: 355764 Skopiuj do schowka
 
 
jaholden 
Starszy Forumowicz


Pomógł: 1 raz
Posty: 59
Wysłany: 06-11-2018, 14:37   

Jesli pliki mają różne wartości, np

TABELA1
Kod:

kolumna_1 | kolumna_2 | kolumna_3
1         | 1         | 1
1         | 1         | 1
1         | 1         | 1

TABELA2
Kod:

kolumna_1 | kolumna_2 | kolumna_3
2         | 2         | 2
2         | 2         | 2
2         | 2         | 2


To w wyniku otrzymuję wszystko (wynik powinien być pusty):
Kod:
kwerenda[0]={"znaleziony rekord":"1","1","1"};
kwerenda[1]={"znaleziony rekord":"1","1","1"};
kwerenda[2]={"znaleziony rekord":"1","1","1"};
kwerenda[3]={"znaleziony rekord":"2","2","2"};
kwerenda[4]={"znaleziony rekord":"2","2","2"};
kwerenda[5]={"znaleziony rekord":"2","2","2"};



Jeśli TABELA2 zaiera coś czego nie ma w TABELA1 to:
TABELA1
Kod:

kolumna_1 | kolumna_2 | kolumna_3
1         | 1         | 1
1         | 1         | 1
1         | 1         | 1

TABELA2
Kod:

kolumna_1 | kolumna_2 | kolumna_3
1         | 1         | 1
1         | 1         | 1
2         | 2         | 2

WYNIK (wynik prawidłowy)
Kod:
kwerenda[0]={"znaleziony rekord":"2","2","2"};


A jeśli jest na dwrót - TABELA1 zawiera element który nie występuje w TABELA2 to:

TABELA1
Kod:

kolumna_1 | kolumna_2 | kolumna_3
1         | 1         | 1
1         | 1         | 1
2         | 2         | 2

TABELA2
Kod:

kolumna_1 | kolumna_2 | kolumna_3
1         | 1         | 1
1         | 1         | 1
1         | 1         | 1

WYNIK (powinno zwrócić pusty wynik)
Kod:
kwerenda[0]={"znaleziony rekord":"2","2","2"};
ID posta: 355771 Skopiuj do schowka
 
 
kulasart
[Usunięty]

Wysłany: 06-11-2018, 15:32   

jaholden napisał/a:
Jesli pliki mają różne wartości (...) To w wyniku otrzymuję wszystko (wynik powinien być pusty):

NIE! Zgodnie z przykładem podanym w pierwszym poście powinieneś dostać wszystko.
Cytat:
A jeśli jest na dwrót - TABELA1 zawiera element który nie występuje w TABELA2 to: (...) WYNIK (powinno zwrócić pusty wynik)

NIE! Zgodnie z przykładem podanym w pierwszym poście w wyniku powinieneś dostać ostatni rekord z pierwszej tabeli.

Nie jest moją winą że zamieszczony przez Ciebie przykład z pierwszego posta jest nieprawidłowy.
Zapytanie dostałeś zgodnie z pierwotnymi wytycznymi.


Potrzebujesz inne? Przeanalizuj zapytanie jakie ode mnie otrzyłałeś. Zapoznaj się z jego konstrukcja i elementami składowymi. Kiedy to zrobisz, to będziesz wiedział co należy zmienić/poprawić.
ID posta: 355775 Skopiuj do schowka
 
 
jaholden 
Starszy Forumowicz


Pomógł: 1 raz
Posty: 59
Wysłany: 06-11-2018, 22:00   

A kto tu mówi o czyjejś winie :) Mój pierwszy wpis faktycznie był nielogiczny na co zwróciłeś uwagę - i go poprawiłem.
Wydaje mi się, że w tym momencie w zwięzły sposób przedstawia problem.
Wynik we wspomnianym poście wskazuje na rekordy z TABELA2 których nie ma w TABELA1 :)
ID posta: 355791 Skopiuj do schowka
 
 
jaholden 
Starszy Forumowicz


Pomógł: 1 raz
Posty: 59
Wysłany: 07-11-2018, 09:18   

Poczytałem i zrobiłem to w ten sposób:

Kod:
    kwerenda = "select * from TABELA2.csv tabela_2 where not exists " & _
                "(select * from TABELA1.csv tabela_1 where " & _
                "tabela_1.kolumna_1 = tabela_2.kolumna_1 and " & _
                "tabela_1.kolumna_2 = tabela_2.kolumna_2 and " & _
                "tabela_1.kolumna_3 = tabela_2.kolumna_3)"

Zauważyłem jednak jezną zastanawiającą rzecz:
Jeśli w TABLE1 w kolumnach dam wartości numeryczne, to kod zwraca błąd.
Tak samo jeśli w TABELA1 są wartości tylko numeryczne a w TABELA2 pojawią się litery...
Jeśli tylko tekstowe lub tylko numeryczne to działa bez zażutu.
Próbowałem przez CONVERT i przez STR(), ale to nie pomogło.


Czy jest jakiś sposób żeby pomimo, że w kolumnie jest "1" i "a" to traktowało to jako ten sam typ znaków i potrwafiło porównać?
ID posta: 355802 Skopiuj do schowka
 
 
jaholden 
Starszy Forumowicz


Pomógł: 1 raz
Posty: 59
Wysłany: 07-11-2018, 11:05   

Próbowałem rozwiązać problem również za pomocą CSTR() w taki sposób

Kod:
...
cstr(tabela_1.kolumna_1) = cstr(tabela_2.kolumna_1)
...


jednak również to nie to
ID posta: 355808 Skopiuj do schowka
 
 
kulasart
[Usunięty]

Wysłany: 07-11-2018, 11:34   

Dodaj w connectionString coś takiego:
Kod:
IMEX=1

Ale i to nie zawsze pomoże. W ekstremalnych przypadkach najlepiej jest użyć pliku schema.ini, którego zawartość wyglądałaby mniej więcej tak:
Kod:
[TABELA1.csv]
ColNameHeader = true
CharacterSet = ANSI
Format = CSVDelimited
Col1=Kolumna1 Text
Col2=Kolumna2 Text
Col3=Kolumna3 Text


[TABELA2.csv]
ColNameHeader = true
CharacterSet = ANSI
Format = CSVDelimited
Col1=Kolumna1 Text
Col2=Kolumna2 Text
Col3=Kolumna3 Text


schema.ini stosowałem w tym (http://www.excelforum.pl/viewtopic.php?t=40093) temacie, gdzie tłumaczyłem "problemy" z odczytem danych przy użyciu ADO.
ID posta: 355812 Skopiuj do schowka
 
 
Wyświetl posty z ostatnich:   
Odpowiedz do tematu
Nie możesz pisać nowych tematów
Nie możesz odpowiadać w tematach
Nie możesz zmieniać swoich postów
Nie możesz usuwać swoich postów
Nie możesz głosować w ankietach
Nie możesz załączać plików na tym forum
Możesz ściągać załączniki na tym forum
Dodaj temat do Ulubionych
Wersja do druku

Skocz do:  

Powered by phpBB modified by Przemo © 2003 phpBB Group
Theme xandgreen created by spleen& Programosy modified v0.3 by warna
Opieka techniczna www.marketingNET.pl

Archiwum

Strona używa plików cookies.

Kliknij tutaj, żeby dowiedzieć się jaki jest cel używania cookies oraz jak zmienić ustawienia cookie w przeglądarce.
Korzystając ze strony użytkownik wyraża zgodę na używanie plików cookies, zgodnie z bieżącymi ustawieniami przeglądarki.
Sprawdź, w jaki sposób przetwarzamy dane osobowe