I have a table where I store detailed information about changes to cars (changes to parts).
For example, here is CarChangeHistory table with few changes to parts in several cars (part names are predefined in another table and can never be different from that default list):
CarChangeHistory
CarGUID PartName PNPNNewValue TimeOfChange
X123 Windshield 344DFSS
X133 Lights BN23112
X899 Battery DNNN222
X433 Battery SM12345
The cars table looks like this:
CarTable
CarGUID Lights Windshield Battery Handle Door Mfg
X123 11111 344DFSS
There are many other similar entries in the CarChangeHistory table.
I want to perform a search and return all items that fall within last 7 days window if following where clause is true:
(Lights LIKE %BN%) AND (Battery = 'DLK222' OR Windshield = true) AND (...) AND (...)
I can convert this to match my table to something like this (this is more logical, pseudo-code. Since it will return nothing if I will use it in SQL query by itself. Since AND conjunction from the above would try to do AND per raw, but I would like to do it per N number of changes/raws for last 7 days):
(PartName = 'Lights' AND PNNewValue LIKE '%BN%')
AND
((PartName = 'Battery' AND PNNewValue = 'DLK222') OR (PartName = 'Windshield'))
AND
(...)
AND
(...)
So.. If I disregard the empty (...)
, using example table above, it would return:
X123 Windshield 344DFSS
X133 Lights BN23112
If my example didn't have line with Lights
, it would return nothing...
I guess the biggest problem is AND conjunction, how do I treat it in such query? How can I use this where clause to perform such searches?
I have tried the following and it works, but I would need to change where clause (by expanding (Lights LIKE %BN%) AND (Battery = 'DLK222' OR Windshield = true)
to (Lights LIKE %BN% OR Windshield = true) OR (Lights LIKE %BN% OR Battery = 'DLK222')
). I guess it can become pretty complex if I have even more conditions.
SELECT TimeOfChange, CarGUID
FROM CarChangeHistory
WHERE (
(((PartName = 'Lights' AND PNNewValue LIKE '%BN%') OR (PartName = 'Battery' AND PNNewValue = 'DLK222')))
OR
(((PartName = 'Lights' AND PNNewValue LIKE '%BN%') OR (PartName = 'Windshield')))
) AND TimeOfChange BETWEEN DATEADD(DAY,-7,GETDATE()) AND GETDATE()
GROUP BY TimeOfChange, CarGUID
HAVING COUNT(*) = 2
Does anyone know better solutions to such problem? What would be best way of converting my logical where clause, which would just return nothing if I run, to something that can actually filter data in table during last 7 days (or whatever is the time window).