What is the best way to provide a "progressive filtering" system for SQL executed from C#?
I have a single table that I'd like to query by providing successive SQL statements to progressively refine the output. The key feature: Each statement would operate on the output of the previous statement. What my code got back would be the output from the last statement.
For example:
SELECT * FROM People WHERE LastName = 'Bond'
SELECT * FROM [whatever was returned from above] WHERE FirstName = 'James'
That's trivial, clearly. Suffice it to say that my real problem is considerably more complex, and it involves multiple "filters" being formed in multiple different code locations in C#. It's complex enough that using multiple WHERE
statements to shoehorn all filtering into a single command has gotten hopelessly confusing.
For clarity, I'm going to call a group of these SQL statements an intention.
I think I can use temporary tables, like this:
SELECT * INTO #MyTempTable FROM People WHERE LastName = 'Bond'
SELECT * FROM #MyTempTable WHERE FirstName = 'James'
Clearly, the SELECT...FROM
could be implied. This is always going to be a single table, so I really just need to specify a series of WHERE
clauses:
LastName = 'Bond'
FirstName = 'James'
The first one would select from the table (People
), and every other would one select from the temp table (MyTempTable
in the example).
Since C# will be executing these successive statements via SqlConnection
, how do I maintain temp table integrity from execution to execution in the same intention, and prevent them from spanning intentions? Additionally, how do I prevent "leftover" temporary tables from existing?
I can use the same SqlCommand
object for each intention (just swapping out the CommandText
each time), so an intention would share a Connection
, but do I have to close the connection to remove those temporary tables?
Another hack-ish way might be to name the temporary table some random value based on a GUID, that only a single intention knows about, so I could be sure that no other intention would "cross paths" with it.
Another idea might be to somehow pass all the SQL into a stored proc that would SQLEXEC
each in order (I really only need the WHERE clauses, since the table will be the same for each).
I can't be the first person to need to do this.
Edit:
A lot of people have pointed out that this should be done by simply concatenating the WHERE
clauses with AND
s. However, here's an example of where it gets more complicated than this --
One example of a filter might be a windowed partition of the table that takes the output of the previous filter, groups on a specific column, calculates aggregates of other columns, and returns a virtual representation of the table for the next filter to work on.
This is just isn't going to fit into a WHERE
clause.
Seriously, the simple x = 'y'
examples from above were just the tip of the iceberg. Some of the filters will need to operate on the entire table to do some more arcane SQL.