Filtrowanie tabeli po kolumnach

0

Witam. Chce napisac zapytanie, ktore w zaleznosci od przekazanego parametru bedzie filtrowalo wyniki. Tzn. na poczatku mamy recordset o 1000 rekordow (jesli nie zadalismy filtrow). Teraz jesli mamy podany GroupId - zmniejsza nam sie ilosc do np. 600, jesli podamy GroupId i ProducedId, powiedzmy do np. 200 a jesli jeszcze dodamy CategoryId, zostaje 40 rekordow. Napisalem do tego takie zapytanie:
DECLARE @Criteria dbo.ProductPropertyTable
INSERT INTO @Criteria VALUES (6, 13, 1);

SELECT 
PP.ProductIndex
, PP.PartName 
, G.[Name] AS GroupName
, M.[Name] AS ProducerName
, C.[Name] AS CategoryName
, G.Id AS GroupId
, M.Id AS ProducerId
, C.Id AS CategoryId
FROM Product.Product AS PP 
LEFT JOIN Dictionary.[Group] AS G ON PP.GroupDictGroupId = G.Id 
LEFT JOIN Dictionary.Manufacturer AS M ON PP.ProducerDictProducerId = M.Id
LEFT JOIN Dictionary.Category AS C ON PP.CategoryDictCategoryId = C.Id
WHERE 
G.Id IN (SELECT GroupId FROM @Criteria) 
AND M.Id IN (SELECT ProducerId FROM @Criteria)
AND C.Id IN (SELECT CategoryId FROM @Criteria)

ale nie radzi sobie ono z wartosciami null w parametrze. Jesli jak w przykladzie przekaze np. 6, 13 i 1 - jest ok ale jesli 6, 13, null - to juz nic nie zwraca. Parametr musi byc tabela - jak w moim przykladzie.
Prosze o podpowiedzi.

0

No to można na 2 sposoby:

#1

WHERE 
    (G.Id IN (SELECT GroupId FROM @Criteria) 
     or (
           exists(select * from  @Criteria where GroupId is null) 
           and G.id is null
         )
    )
AND (M.Id IN (SELECT ProducerId FROM @Criteria)
     or (
           exists(select * from @Criteria where ProducerId is null) 
           and M.id is null
         )
    )
AND (C.Id IN (SELECT CategoryId FROM @Criteria)
     or (
           exists(select * from  @Criteria where CategoryId is null) 
           and C.id is null
         )
    )

#2 zakładając że id > 0

WHERE 
isnull(G.Id,-1) IN (SELECT isnull(GroupId,-1) FROM @Criteria) 
AND isnull(M.Id,-1) IN (SELECT isnull(ProducerId,-1) FROM @Criteria)
AND isnull(C.Id,-1) IN (SELECT isnull(CategoryId,-1) FROM @Criteria)

UPDATE:

Można jeszcze ustawić opcje:

SET ANSI_NULLS OFF

I wtedy zadziała, jak oczekujesz bez zmian w zapytaniu, ale to nie wiadomo kiedy zacznie generować błędy i nie zaleca się stosowania: https://docs.microsoft.com/en-us/sql/t-sql/statements/set-ansi-nulls-transact-sql

1

Odpowiadaj w postach:

No niestety rozwiazanie nie dziala. Rozumiem chyba zamysl bo tez podobnie probowalem. Jak rozumiem probujesz stworzyc prawdziwe warunki, -1 = -1 ale nie dziala chyba dlatego, ze G.Id, M.Id i C.Id nie sa NULL
SET ANSI_NULLS OFF, tez nie zmienilo sytuacji

Czyli rozumiem, ze ty nie potrzebujesz sprawdzać null=null tylko zignorować filtrowanie jeśli nie jest podany warunek (null)?

Jeżeli tak to:

WHERE 
    (G.Id IN (SELECT GroupId FROM @Criteria) 
     OR 
      EXISTS(SELECT * FROM  @Criteria WHERE GroupId IS NULL) 
    )
AND (
     M.Id IN (SELECT ProducerId FROM @Criteria)
     OR 
     EXISTS(SELECT * FROM @Criteria WHERE ProducerId IS NULL) 
    )
AND (
     C.Id IN (SELECT CategoryId FROM @Criteria)
     OR 
      EXISTS(SELECT * FROM  @Criteria WHERE CategoryId IS NULL) 
    )
0

Tak, dokladnie o to mi chodzilo. Jesli jest przekazany null to warunek ma byc pomijany. Dzieki. Teraz dziala jak nalezy

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