Jak przefiltrować tabelę ?

0

Witam,
Zacznijmy od tego że wszystkiego dobrego w nowym roku ;-)...

A teraz do problemu:

Poszukuje rozwiązania w jaki sposób połączyć / przefiltrować 2 tabele w MS SQL:

Tabela 1 "Urzadzenia" zawiera dane:

-Numer_urzadzenia
-ustawienia_1
-ustawienia_2
-ustawienia_3
-ustawienia_4

Tabela 2 "Odczyt" zawiera dane:

-Numer_urzadzenia
-Data
-Odczyt_parametr_1
-Odczyt_parametr_2
-Odczyt_parametr_3
-Odczyt_parametr_4

Oczekiwany efekt jaki chcę osiągnąć to lista zawierająca dane z Tabeli 1 które nie zostały jeszcze odczytane w dniu dzisiejszym (brak wpisu w Tabeli 2).

Próbowałem:

SELECT dbo.Urzadzenia.Numer_urzadzenia, dbo.Urzadzenia.ustawienia_1,  dbo.Urzadzenia.ustawienia_2,  dbo.Urzadzenia.ustawienia_3,  dbo.Urzadzenia.ustawienia_4
FROM dbo.Urzadzenia 
INNER JOIN
dbo.Odczyt ON dbo.Odczyt.Data NOT LIKE '03.01.2025' AND dbo.Urzadzenia.Numer_urzadzenia = dbo.Numer_urzadzenia

Niestety ale mam efekt taki, że otrzymuje listę danych z Tabeli1 powielone o wszystkie poprzednie dni, oraz jest brak urządzenia które zostało nowo dodane do Tabeli1 i nie było nigdy odczytywane...

Próbowałem również użyć funkcji "NOT IN" jednak po wykonaniu chodziaż jednego wpisu z dzisiejszą datą lista robi się pusta..

Proszę o pomoc

0

LEFT ANTI JOIN :-)

0
ledi12 napisał(a):

LEFT ANTI JOIN :-)

Hmm a w jaki sposób to zastosować ?? otrzymuje błąd po wpisaniu "ANTI"

1
kazik89 napisał(a):

Witam,
Zacznijmy od tego że wszystkiego dobrego w nowym roku ;-)...

SELECT dbo.Urzadzenia.Numer_urzadzenia, dbo.Urzadzenia.ustawienia_1,  dbo.Urzadzenia.ustawienia_2,  dbo.Urzadzenia.ustawienia_3,  dbo.Urzadzenia.ustawienia_4
FROM dbo.Urzadzenia 
INNER JOIN
dbo.Odczyt ON dbo.Odczyt.Data NOT LIKE '03.01.2025' AND dbo.Urzadzenia.Numer_urzadzenia = dbo.Numer_urzadzenia

Wszystkiego dobrego!

NIe mam teraz dostępu do bazy, więc piszę "z palca", ale spróbuj mniej więcej tak:

SELECT dbo.Urzadzenia.Numer_urzadzenia, dbo.Urzadzenia.ustawienia_1,  dbo.Urzadzenia.ustawienia_2,  dbo.Urzadzenia.ustawienia_3,  dbo.Urzadzenia.ustawienia_4
FROM dbo.Urzadzenia 
LEFT JOIN
dbo.Odczyt ON  dbo.Urzadzenia.Numer_urzadzenia = dbo.Odczyt.Numer_urzadzenia
WHERE dbo.Odczyt.Data IS NULL
0

Ogólnie dziękuje za szybką reakcje ... ale:

SELECT dbo.Urzadzenia.Numer_urzadzenia, dbo.Urzadzenia.ustawienia_1,  dbo.Urzadzenia.ustawienia_2,  dbo.Urzadzenia.ustawienia_3,  dbo.Urzadzenia.ustawienia_4
FROM dbo.Urzadzenia 
LEFT JOIN
dbo.Odczyt ON  dbo.Urzadzenia.Numer_urzadzenia = dbo.Odczyt.Numer_urzadzenia
WHERE dbo.Odczyt.Data IS NULL

Działa w taki sposób że zwraca tylko listę nowych urządzeń które nie były jeszcze nigdy odczytane - pewnie ze względu na "null"

1
kazik89 napisał(a):

Ogólnie dziękuje za szybką reakcje ... ale:

SELECT dbo.Urzadzenia.Numer_urzadzenia, dbo.Urzadzenia.ustawienia_1,  dbo.Urzadzenia.ustawienia_2,  dbo.Urzadzenia.ustawienia_3,  dbo.Urzadzenia.ustawienia_4
FROM dbo.Urzadzenia 
LEFT JOIN
dbo.Odczyt ON  dbo.Urzadzenia.Numer_urzadzenia = dbo.Odczyt.Numer_urzadzenia
WHERE dbo.Odczyt.Data IS NULL

Działa w taki sposób że zwraca tylko listę nowych urządzeń które nie były jeszcze nigdy odczytane - pewnie ze względu na "null"

No tak, słuszna uwaga.

a to:

WHERE (dbo.Odczyt.Data = '03.01.2025' ) IS NULL

0
select * from tabela A where not exists (select 1 from tabela b where a.numer_urzadzenia = b.numer_urzadzenia and b.data = ....)
0

Polecam sobie przerobić wszystkie zadanka tutaj: https://pgexercises.com/ i podejść do zagadki filtrowania jeszcze raz, na pewno Ci to pomoże :)

1
piotrpo napisał(a):
select * from tabela A where not exists (select 1 from tabela b where a.numer_urzadzenia = b.numer_urzadzenia and b.data = ....)

To co napisał tutaj @piotrpo powinno zadziałać. Jaki masz typ danych na tej kolumnie z datą?

Not exists nie działa na zasadzie not in - powinna pojawić się cała lista.
EDIT: Dobra przeczytałem powyżej, że jest jako nchar. Po prostu zrób convert na końcu

select * 
from tabela A 
where not exists 
    (select 1 
     from tabela b 
     where a.numer_urzadzenia = b.numer_urzadzenia
     AND CAST(data AS DATE) = CAST(GETDATE() AS DATE)
     ); 
0
AmikCS napisał(a):
piotrpo napisał(a):
select * from tabela A where not exists (select 1 from tabela b where a.numer_urzadzenia = b.numer_urzadzenia and b.data = ....)

To co napisał tutaj @piotrpo powinno zadziałać. Jaki masz typ danych na tej kolumnie z datą?

Not exists nie działa na zasadzie not in - powinna pojawić się cała lista.
EDIT: Dobra przeczytałem powyżej, że jest jako nchar. Po prostu zrób convert na końcu

select * 
from tabela A 
where not exists 
    (select 1 
     from tabela b 
     where a.numer_urzadzenia = b.numer_urzadzenia
     AND CAST(data AS DATE) = CAST(GETDATE() AS DATE)
     ); 

Dzięki za odpowiedź... Twój kod podczas uruchomienia zwraca błąd :"Conversion failed when converting date and/or time from character string", ale wyświetla wynik z tym że tylko 1 pozycje taką która została odczytana wczoraj - brak reszty pozycji, między innymi urządzeń dodanych do bazy których odczytu jeszcze nigdy nie było.

Kurcze niby proste zadanie a jednak nie tak jak się wydaje ... w skrócie chce wyświetlić liste urządzeń z Tabeli1 które nie zostały odczytane dzisiaj lub kiedykolwiek ... po zmianie daty na jutro tj. 04.01.2025 lista powinna się zaktualizować i na nowo wyświetlać wszystkie urządzenia do odczytu

1
kazik89 napisał(a):
AmikCS napisał(a):
piotrpo napisał(a):
select * from tabela A where not exists (select 1 from tabela b where a.numer_urzadzenia = b.numer_urzadzenia and b.data = ....)

To co napisał tutaj @piotrpo powinno zadziałać. Jaki masz typ danych na tej kolumnie z datą?

Not exists nie działa na zasadzie not in - powinna pojawić się cała lista.
EDIT: Dobra przeczytałem powyżej, że jest jako nchar. Po prostu zrób convert na końcu

select * 
from tabela A 
where not exists 
    (select 1 
     from tabela b 
     where a.numer_urzadzenia = b.numer_urzadzenia
     AND CAST(data AS DATE) = CAST(GETDATE() AS DATE)
     ); 

Dzięki za odpowiedź... Twój kod podczas uruchomienia zwraca błąd :"Conversion failed when converting date and/or time from character string", ale wyświetla wynik z tym że tylko 1 pozycje taką która została odczytana wczoraj - brak reszty pozycji, między innymi urządzeń dodanych do bazy których odczytu jeszcze nigdy nie było.

Kurcze niby proste zadanie a jednak nie tak jak się wydaje ... w skrócie chce wyświetlić liste urządzeń z Tabeli1 które nie zostały odczytane dzisiaj lub kiedykolwiek ... po zmianie daty na jutro tj. 04.01.2025 lista powinna się zaktualizować i na nowo wyświetlać wszystkie urządzenia do odczytu

No to kurczę z tą kolumną będą problemy. Spróbuj zrobić tak:

AND ISDATE(O.Data) = 1 - sprawdzi to nam czy w kolumnie data jest poprawna data

AND CAST(O.Data AS DATE) = CAST(GETDATE() AS DATE) - konwersja daty + bierze tylko dzisiejszą date

WHERE O.Numer_urzadzenia IS NULL -- szukamy urządzeń, które nie mają żadnego odczytu

SELECT 
    U.Numer_urzadzenia,
     U.ustawienia_1,
    U.ustawienia_2,
    U.ustawienia_3,
    U.ustawienia_4
FROM 
    Urzadzenia U
LEFT JOIN 
    Odczyt O
ON 
    U.Numer_urzadzenia = O.Numer_urzadzenia
    AND ISDATE(O.Data) = 1 
    AND CAST(O.Data AS DATE) = CAST(GETDATE() AS DATE)
WHERE 
    O.Numer_urzadzenia IS NULL;

Jeżeli powyższy kod też nie zadziała to już niezła lipa, wtedy zrób:

SELECT Data
FROM Odczyt
WHERE ISDATE(Data) = 0; -- Znajduje niepoprawne daty

Powyższy kod znów pokaże Ci wartośći, które nie są poprawną datą i to może powodować nam błąd przy próbie konwersji.

Na pewno moim zdaniem warto zmienić typ danych z tej kolumny - DATE / DATETIME

0
AmikCS napisał(a):
kazik89 napisał(a):
AmikCS napisał(a):
piotrpo napisał(a):
select * from tabela A where not exists (select 1 from tabela b where a.numer_urzadzenia = b.numer_urzadzenia and b.data = ....)

To co napisał tutaj @piotrpo powinno zadziałać. Jaki masz typ danych na tej kolumnie z datą?

Not exists nie działa na zasadzie not in - powinna pojawić się cała lista.
EDIT: Dobra przeczytałem powyżej, że jest jako nchar. Po prostu zrób convert na końcu

select * 
from tabela A 
where not exists 
    (select 1 
     from tabela b 
     where a.numer_urzadzenia = b.numer_urzadzenia
     AND CAST(data AS DATE) = CAST(GETDATE() AS DATE)
     ); 

Dzięki za odpowiedź... Twój kod podczas uruchomienia zwraca błąd :"Conversion failed when converting date and/or time from character string", ale wyświetla wynik z tym że tylko 1 pozycje taką która została odczytana wczoraj - brak reszty pozycji, między innymi urządzeń dodanych do bazy których odczytu jeszcze nigdy nie było.

Kurcze niby proste zadanie a jednak nie tak jak się wydaje ... w skrócie chce wyświetlić liste urządzeń z Tabeli1 które nie zostały odczytane dzisiaj lub kiedykolwiek ... po zmianie daty na jutro tj. 04.01.2025 lista powinna się zaktualizować i na nowo wyświetlać wszystkie urządzenia do odczytu

No to kurczę z tą kolumną będą problemy. Spróbuj zrobić tak:

AND ISDATE(O.Data) = 1 - sprawdzi to nam czy w kolumnie data jest poprawna data

AND CAST(O.Data AS DATE) = CAST(GETDATE() AS DATE) - konwersja daty + bierze tylko dzisiejszą date

WHERE O.Numer_urzadzenia IS NULL -- szukamy urządzeń, które nie mają żadnego odczytu

SELECT 
    U.Numer_urzadzenia,
     U.ustawienia_1,
    U.ustawienia_2,
    U.ustawienia_3,
    U.ustawienia_4
FROM 
    Urzadzenia U
LEFT JOIN 
    Odczyt O
ON 
    U.Numer_urzadzenia = O.Numer_urzadzenia
    AND ISDATE(O.Data) = 1 
    AND CAST(O.Data AS DATE) = CAST(GETDATE() AS DATE)
WHERE 
    O.Numer_urzadzenia IS NULL;

Jeżeli powyższy kod też nie zadziała to już niezła lipa, wtedy zrób:

SELECT Data
FROM Odczyt
WHERE ISDATE(Data) = 0; -- Znajduje niepoprawne daty

Powyższy kod znów pokaże Ci wartośći, które nie są poprawną datą i to może powodować nam błąd przy próbie konwersji.

Na pewno moim zdaniem warto zmienić typ danych z tej kolumny - DATE / DATETIME

Zrobiłem coś takiego:

select * 
from tabela A 
where not exists 
    (select 1 
     from tabela b 
     where a.numer_urzadzenia = b.numer_urzadzenia
     AND Data LIKE CONVERT(VARCHAR, GETDATE(), 104)
     ); 

I na chwile obecną działa - oczywiście będę próbował z konwersja daty jeszcze aby to "wyprostować" jak się należy... Dam znać jakie będą tego efekty 😀

Dziękuje wielkie za pomoc ! 😀

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.