Using column variables in my WHERE clause - sql

I have two tables (tableA and tableB) both with a name column. tableA's name column might be called NAME, tableB's column might be called FULLNAME, but they both are supposed to have the same value.
I am to write a query that pulls member id's (from either table) where these two column values are not the same. However, I'd like to pass the column names I'm checking via parameter, as this will be going in an SSRS report and in the future i'd like to be able to use it to compare any other column between these two tables.
Something like this:
DECLARE #COLUMN_A VARCHAR(50), #COLUMN_B VARCHAR(50)
/* COLUMN PARAMS WILL BE PASSED IN VIA SSRS */
SELECT
DISTINCT(MEMBER_ID)
FROM
TABLE_A
JOIN TABLE_B
ON (TABLE_A.MEMBER_ID = TABLE_B.MEMBER_ID)
WHERE
#COLUMN_A <> #COLUMN_B
Is something like this possible?
edit:
Or might something like this work?
DECLARE
#column VARCHAR(50)
SELECT #column = 'FIRST_NAME';
SELECT DISTINCT
MEMBR_ID,
case
when #column='FIRST_NAME' then MEMBR_FIRST_NAME
when #column='LAST_NAME' then MEMBR_LAST_NAME
end TABLE_1,
case
when #column='FIRST_NAME' then FIRSTNAME
when #column='LAST_NAME' then LASTNAME
end TABLE_2,
#column
FROM
TABLE_1
JOIN TABLE_2
ON (TABLE_1.MEMBR_ID = TABLE_2.MEMBR_ID)
WHERE
TABLE_1.#column <> TABLE_2.#column

Is something like this possible?
Technically, the syntax is fine. The where will be comparing two constant strings. The results will be either all rows or no rows, depending on whether the two strings are the same.
Do these evaluate to the columns? No, they do not. You cannot pass parameters into a SQL statement for identifiers -- column names, table names, schema names, database names, function names, or operators (for example).
You can do this using dynamic SQL, but you have to plug the names in:
DECLARE #sql NVARCHAR(MAX);
SET #sql = '
SELECT DISTINCT A.MEMBER_ID
FROM TABLE_A A JOIN
TABLE_B B
ON A.MEMBER_ID = B.MEMBER_ID
WHERE A.#COLUMN_A <> B.#COLUMN_B
';
SET #sql = REPLACE(#sql '#COLUMN_A', COLUMN_A);
SET #sql = REPLACE(#sql '#COLUMN_B', COLUMN_B);
exec sp_executesql #sql;

Related

why I need a dynamic query for "column value from a query"

For example this returns a value from a query, which I will then use as a column name.
#A=Select top 1 productid from productlist order by timestamp desc
then I would like this "productid" A to be used in the other table
Select #A from customerlist
then the result is #A value instead of field value in customerlist.
When I use dynamic query, I can get right result.
Why?
(I know I can use join but because this productlist table is dynamic, so let's assume it is a sub query)
You need "dynamic SQL" because SQL will NOT allow you to use a parameter as a column name or a table name. You can only use parameters for data values such as in a where clause where column1 = #val
set #A = 'çolumn1'
Select #A from customerlist -- this fails because it is not allowed
Dynamic SQL is a "hack" to get around those restrictions as the SQL statement is placed into a string along with any value held by parameters.
set #A = 'çolumn1'
set #SQL = 'Select ' + #A + ' from customerlist;'
execute #SQL -- this works, the SQL statement is valid with no parameters as column names
The string formed as #SQL is a complete sql statement without needing any parameters as column names.
Note: the syntax I used here is incomplete and is based on MS SQL Server, different databases will use a different, but similar, syntax.

How to write an attribute name to the select query dynamically

I have a table including:
ID Name Period0Id Period1Id Period2Id
What I would like to receive data based on a user-defined parameter #check.
Lets assume:
declare #check int = 1;
In this case I need to get Period1Id value from the table. So I need to have something like that:
Select ID, Name, StatusId = Period + #check + Id -- #check is the parameter
From mytable
However, my query is not working. How can I fix this?
Your table looks like it is not in first normal form.
Instead of three columns for Period0Id to Period2Id you could have a column for PeriodIndex with values of (0,1,2) and a single column for PeriodId and then it would be just a WHERE PeriodIndex = #Check
You can't select a column using string interpolation with a variable as you are attempting. You can use dynamic SQL to create the SQL String dynamically. Or simply hardcode the options if they all have the same dataype.
Select ID,
Name,
StatusId = CASE #Check WHEN 0 THEN Period0Id
WHEN 1 THEN Period1Id
WHEN 2 THEN Period2Id
END
From mytable
Here is an alternative way that will create dynamic columns, which is essentially using your original query:
DECLARE #check VARCHAR = 1
DECLARE #sqlquery NVARCHAR(MAX)
SET #sqlquery = N'SELECT ID, Name, StatusId = Period'+#check+'Id
FROM mytable'
EXEC sp_executesql #sqlquery

Query fields after query multiple tables on multiple databases

I am trying to do a interesting query. I have a lot of databases and they have a table with the same name (e.g : mytable). I want to find something in this table but searching all this table occurrence on the server.
I tried:
sp_msforeachdb 'Select * from Sysobjects where name=''mytable'''
This lists all the 'mytable' tables on the server.
I also used
select * from [table].[dbo].[mytable] where myclause
I tried to join these two queries, but I am was not able to find the correct way to do that (if there is a way).
I tried case, join, inner join but it is really hard to get what I want.
Try this:
sp_msforeachdb 'insert into MyMasterDB.dbo.ResultsTable select * from [?].dbo.[MyTable] where myclause'
OR (with db name in results)
DECLARE #SQL AS VARCHAR(MAX)
select #SQL = 'insert into MyMasterDB.dbo.ResultsTable select ? as DB_Name, col1, cast (col2 as varchar (50)), col3 from [?].dbo.[MyTable] where myclause'
sp_msforeachdb #SQL
To escape ' (single quote) use '' (two double quotes)

Complex query filter using Like() in T-SQL

I'm writing a SQL script that we want our accounting team to be able to edit, without dealing with engineering.
The general idea is to have a .sql script, which defines some variables at the top of the query, and then has several complex queries below it that use those variables.
The problem we have is that we want the accounting team to be able to specify the filter to use. For example:
DECLARE #year INT
DECLARE #month INT
DECLARE #filter VARCHAR(30);
SET #year = 2010
SET #month = 7
SET #filter = '%test%'
Here the team can change the month and the year that the subsequent queries return. They can also define ONE filter element, in this example, excluding any records where the username has the string 'test' in it.
My question is whether or not there is a way to specify OR's to a LIKE(). Eg, ideally we'd have the #filter variable as something like '%test%, or %other%. Now I know that's not real syntax, but I'm wondering if there is syntax that lets me achieve that. I've scowered MSDN on the LIKE() syntax with no joy. Should I use some different query expression?
Probably the simplest thing to do would be to just have multiple parameters, though it's not pretty:
SET #filter_1 = '%test%'
SET #filter_2 = '%foo%'
SET #filter_3 = '%'
SET #filter_4 = '%'
SELECT *
FROM BAR
WHERE var LIKE #filter_1
OR var LIKE #filter_2
OR var LIKE #filter_3
OR var LIKE #filter_4
OR var LIKE #filter_5
By defaulting them to %, they will always match by default.
You could also use dynamic SQL and a local table variable. Basically, create a local table with one column, allow them to change the INSERT statements into that table, then define a loop that iterates over the contents of that table to dynamically generate the LIKE clauses. It would work, but it would be a bit more code. The example above is quick and dirty, but I'd guess it's probably sufficient for what you need to do.
I'd use a join with a LIKE predicate. You can execute the following code sample in a query window to see how this works:
DECLARE #tblFilter TABLE
(sFilter nvarchar(MAX) NOT NULL);
INSERT #tblFilter
SELECT * FROM (VALUES ('%one%'), ('%two%'), ('%three%')) v(s);
DECLARE #tblData TABLE
(iId int NOT NULL PRIMARY KEY IDENTITY,
sData nvarchar(MAX));
INSERT #tblData(sData)
SELECT * FROM (VALUES ('one'), ('two three'), ('four')) v(s);
SELECT DISTINCT iId
FROM #tblData d
JOIN #tblFilter f ON d.sData LIKE f.sFilter;
I assume that the different query strings are in the #tblFilter table, which could be a TVP, coming from XML values, from comma-separated values, from a temp table or whatever.

SQL query like filter

I need to execute a search query in SQL Server where I need to filter out data based upon an user input textfield.
The problem is, this query needs to be executed on several tables (so I only know the tablecolumns at runtime).
This is the query I have:
SELECT * FROM [BTcegeka.C2M].[dbo].[Lookup_Country] WHERE Name LIke '%test%'
Now the problem is I need to do the Like function on every column (I only know the columnname at runtime) in the table. I am calling this query from an ASP.NET website. The user selects a table from a dropdownlist and can then enter the search field.
This is what I really want to accomplish:
SELECT * FROM [BTcegeka.C2M].[dbo].[Lookup_Country] WHERE * LIke '%test%'
Obviously 'Where * Like' Fails. How can I accomplish this?
You can query all columns in a table like:
select name from sys.columns where object_id = object_id('YourTable')
Then you can construct a query that does a like for each column.
Another approach is to create a calculated column called SearchField that contains a concatenation of all strings you'd like to search for. Then you can search like:
create table #tmp (id int identity, col1 varchar(10), col2 varchar(10),
SearchField as col1 + '|' + col2 persisted)
insert #tmp (col1, col2) values
('alfa', 'beta'),
('gamma', 'DELTA'),
('GAMMA', 'delta')
select * from #tmp where SearchField like '%alfa%'
Try using your SQL query like this.
SELECT * FROM [BTcegeka.C2M].[dbo].[Lookup_Country]
WHERE
COL1 LIke '%test%'
OR COL2 LIke '%test%'
OR COL3 LIke '%test%'
You may use AND instead of OR if your requirement needs that.
If you know the column names at run time, then you should build you query in .NET before passing it to sql. You can build it with the correct column name. This way you can account also for the type of the column you search in.
Careful though this path you chose is prone to SQL injection so before sending a query to the SQL you should check it.
If you really need to do this you can search in sqlserver meta tables and find the description of selected user table. Make a good use of this data is easy and you can make any sql you want with this information, but performance may not the that good
you have to use dynamic sql for implementing this. Your column name needs to be passed as parameter to this stored procedure or if you dont want to create stored procedure just declare one paramter and assign the value selected from the drop down list to it and use that in the query.
create procedure sp_dynamicColumn
(
#columnName varchar(10)
)
as
begin
declare #DYNAMICSQL nvarchar(4000);
SET #DYNAMICSQL = 'Select * from [BTcegeka.C2M].[dbo].[Lookup_Country] where '+ #columnName + ' like ''%test%'''
EXECUTE SP_EXECUTESQL #DYNAMICSQL
end
go