Zapytanie zwraca za dużo wyników niż powinno

0

Witam!
Jestem nowy tutaj. Bardzo proszę o wybaczenie tytułu, nie wiem jak nazwać to z czym mam problem.

	select * from dbo.Zdarzenia
	where ZdR_UdPId = 8487

ZdR_ZdRId | ZdR_TzDId | ZdR_Data | ZdR_UsRId | ZdR_Uwagi | ZdR_SrWId | ZdR_UdPId
---------------- | ------------------- | ------------------- | ------------------- | ------------------- | -------------------
5826 |3 |2013-09-16 0000.000 |NULL |NULL |1 |8487
6548 |1 |2015-08-28 0000.000 |8c1911e5-0330-4e8c-a464-c32e42eb5c83 |NULL |1 |8487
6549 |1 |2017-08-24 0000.000 |8c1911e5-0330-4e8c-a464-c32e42eb5c83 |NULL |1 |8487

Potrzebuje z tego rekord z maksymalną datą więc:

SELECT MAX(z2.ZdR_Data) AS max_date FROM dbo.Zdarzenia z2 where z2.ZdR_UdPId = 8487 group by z2.ZdR_UdPId
max_date
2017-08-24 0000.000

Pełne zapytanie:

SELECT z.* FROM dbo.Zdarzenia z
  JOIN ( SELECT distinct MAX(z2.ZdR_Data) AS max_date FROM dbo.Zdarzenia z2 group by z2.ZdR_UdPId) m
    ON m.max_date = z.ZdR_Data
	where z.ZdR_UdPId = 8487

ZdR_ZdRId | ZdR_TzDId | ZdR_Data | ZdR_UsRId | ZdR_Uwagi | ZdR_SrWId | ZdR_UdPId
---------------- | ------------------- | ------------------- | ------------------- | ------------------- | -------------------
6548 |1 |2015-08-28 0000.000 |8c1911e5-0330-4e8c-a464-c32e42eb5c83 |NULL |1 |8487
6549 |1 |2017-08-24 0000.000 |8c1911e5-0330-4e8c-a464-c32e42eb5c83 |NULL |1 |8487

Dlaczego wyciąga dwa rekordy skoro max data jest jedna i na rok 2017?
Dzieje się tak w przypadku wszystkich rekordów, które mają ten sam schemat wpisów.

0

Jedyne co mi przychodzi do głowy to zmień joina na left joina lub Right joina. Sam join wyciąga cross z dwóch tabel wiec możesz miec po obu stronach puste kolumny a przy lefcie czy righcie tylko z jednej.

0

LEFT JOIN zwraca wszystkie, RIGHT JOIN zwraca te same dwa rekordy co sam JOIN.

0

Całe zapytanie wygląda tak:

SELECT z.* FROM dbo.Zdarzenia z
  JOIN ( SELECT distinct MAX(z2.ZdR_Data) AS max_date FROM dbo.Zdarzenia z2 group by z2.ZdR_UdPId) m
    ON m.max_date = z.ZdR_Data
	left join dbo.UrzadzeniaPodatnika up on z.ZdR_UdPId = up.UdP_UdPId
	where m.max_date >= (case when (up.UdP_CzyDwaLata = 1) then dateadd(year, -2, GETDATE()) else dateadd(year, -1, GETDATE()) end) 
	and m.max_date <= (case when (up.UdP_CzyDwaLata = 1) then dateadd(year, -2, dateadd(day, 7, GETDATE())) else dateadd(year, -1, dateadd(day, 7, GETDATE())) end)
	and up.UdP_Aktywna = 1 
	and up.UdP_DoOdczytu = 0 
	and (z.ZdR_TzDId = 1 or z.ZdR_TzDId = 3) order by m.max_date

Reszta nie ma wpływu na wynik, ponieważ na samym początku powinien mi wyciągnąć rekord z datą najwyższą.

0

dzieje się tak, ponieważ podazapytania z ostatnią datą nie ograniczasz do jednego ZdR_UdPId, więc gdy masz więcej różnych ZdR_UdPId z różnymi datami to będziesz miał więcej rekordów zwracanych.
możesz to rozwiązać albo tak:

SELECT z.* FROM dbo.Zdarzenia z
  JOIN ( SELECT MAX(z2.ZdR_Data) AS max_date FROM dbo.Zdarzenia z2 where z2.ZdR_UdPId=8487 GROUP BY z2.ZdR_UdPId) m
    ON (m.max_date = z.ZdR_Data)
    WHERE z.ZdR_UdPId = 8487

albo tak:

SELECT z.* FROM dbo.Zdarzenia z
  JOIN ( SELECT MAX(z2.ZdR_Data) AS max_date, z2.ZdR_UdPId FROM dbo.Zdarzenia z2 GROUP BY z2.ZdR_UdPId) m
    ON (m.max_date = z.ZdR_Data and z.ZdR_UdPId=m.ZdR_UdPId)
    WHERE z.ZdR_UdPId = 8487
0
AdamWox napisał(a):

Pełne zapytanie:

SELECT z.* FROM dbo.Zdarzenia z
  JOIN ( SELECT distinct MAX(z2.ZdR_Data) AS max_date FROM dbo.Zdarzenia z2 group by z2.ZdR_UdPId) m
    ON m.max_date = z.ZdR_Data
	where z.ZdR_UdPId = 8487

A z ciekawości zamień to na:

 SELECT z.* FROM dbo.Zdarzenia z
   Where z.ZdR_Data = ( SELECT distinct MAX(z2.ZdR_Data) FROM dbo.Zdarzenia z2 
                                        Where z.ZdR_UdPId = z2.ZdR_UdPId
                                        group by z2.ZdR_UdPId)
	and z.ZdR_UdPId = 8487

Edit: No własnie mialem pisac to co kolega u gory (tylko tel. zadzownil :D ) ... to moje rozwiazanie powinno tez rozwiazac problem ;)

0

Mistrzostwo świata! Dzięki bardzo za pomoc :D

1 użytkowników online, w tym zalogowanych: 0, gości: 1