DECLARE @AdDetails TABLE
(
AdDetailID INT,
AdID INT,
PropertyName VARCHAR(20),
PropertyValue VARCHAR(20)
)
INSERT INTO @AdDetails
( AdDetailID, AdID, PropertyName, PropertyValue )
VALUES
(2, 28, 'Color', 'Red'),
(3, 28, 'Speed', '100'),
(4, 27, 'Color', 'Red'),
(5, 28, 'Fuel', 'Petrol'),
(6, 27, 'Speed', '70');
--Col1
DECLARE @ColorValue VARCHAR(20) = 'Red'
--Col2
DECLARE @SpeedValue INT = 90
DECLARE @SpeedType VARCHAR(2) = '>'
--Col3
DECLARE @FuelValue VARCHAR(20) = null
SELECT DISTINCT a.AdID FROM @AdDetails a
INNER JOIN
(
SELECT *
FROM @AdDetails
WHERE @ColorValue IS NULL
OR @ColorValue = PropertyValue
) Color
ON Color.AdID = a.AdID
INNER JOIN
(
SELECT *
FROM @AdDetails
WHERE @SpeedType IS NULL
UNION
SELECT *
FROM @AdDetails
WHERE PropertyName = 'Speed'
AND ((@SpeedType = '>' AND CONVERT(INT, PropertyValue) > @SpeedValue)
OR (@SpeedType = '<' AND CONVERT(INT, PropertyValue) < @SpeedValue)
OR (@SpeedType = '=' AND CONVERT(INT, PropertyValue) = @SpeedValue))
) AS Speed
ON Speed.AdID = a.AdID
INNER JOIN
(
SELECT *
FROM @AdDetails
WHERE @FuelValue IS NULL
OR (@FuelValue = PropertyValue)
) AS Fuel
ON Fuel.AdID = a.AdID
I add one inner join clause per property type (with some overrides), your sql query would pass all of the possible property type info in one go nulling out whatever they don't want. very ugly code though as it grows.