how to check a dynamic column name is null - sql

I have a table like below which has several columns along with series of numbers as well like the below:
Name: JLEDG
name
user_val_1
user_val_2
user_val_3
user_val_4
One
Two
Three
Three
Three
DECLARE #myvar int = 3;
So I would like to do the following which is not working:
SELECT * FROM JLEDG WHERE ('user_val_' + #myvar) IS NULL;
Expect the sql should be
SELECT * FROM JLEDG WHERE user_val_3 IS NULL;

You can only do that in dynamic SQL. You seem to have a problem with your data model. You shouldn't be storing values splayed across columns like that. You should have another table with one row per value.
One thing you can do is unpivot (using apply) and then filter:
select j.*
from jledg j cross apply
(values (1, user_val_1), (2, user_val_2), . . .
) v(which, user_val)
where which = #myvar;
The alternative is to use dynamic SQL (sp_executesql), but that seems quite cumbersome when you could just fix the data model.

SQL Server is declarative by design, and does not support macro substitution. As Gordon mentioned in his solution (+1), Dynamic SQL is just another option
Example
Declare #myvar int = 3
Declare #SQL varchar(max) = concat('SELECT * FROM JLEDG WHERE user_val_',#myvar,' IS NULL;')
Exec(#SQL)

Related

T-SQL get substring

I am looking to get an order number from a column named KEY_Ref, this ref column have various contents, but some rows look like this
LINE_NO=15^ORDER_NO=176572^RELEASE_NO=1^
Now I am interested in getting the value for ORDER_NO (176572 in this case)
How would I (In SQL Server) go about getting this (Or other) value from the main string
The logic is always
key1=value1^key2=value2^key3=value3^
You can use string_split():
select t.*, s.orderno
from t outer apply
(select stuff(s.value, 1, 9, '') as orderno
from string_split(t.key_ref, '^') s
where s.value like 'ORDER_NO=%'
) s;
Here is a db<>fiddle.
this is going to be a bit lengthy answer however if your SQL server version doesn't support string_split function you may use this.
declare #str varchar(100) = 'LINE_NO=15^ORDER_NO=176572^RELEASE_NO=1^'
declare #substr1 varchar(50) = substring(#str,charindex('^',#str)+1,len(#str))
declare #substr2 varchar(50) = substring(#substr1,charindex('=',#substr1)+1,charindex('^',#substr1)-charindex('=',#substr1)-1)
select #substr2 as 'order number'
the final variable will produce the desired value and you must merge the above queries to a single query that can fetch the value from the table in a single select statement.
this will work only if the pattern doesn't deviate from the one you've mentioned.

SELECT statement having where clause with dynamic condition

I have a small select query which picks data from a table as per the parameter passed to a procedure.
DECLARE #flgParam bit
.
.
SELECT *
FROM tablename
WHERE flgRequired like <If #flgparam is 0 then 1 or zero , Else 1>
what is the best way to construct the where clause
I'm thinking something like this:
SELECT *
from tablename
where #flgparam is null or #flgcolumnval = #flgparam;
#flgparam is declared as a bit, so it can only take on the values of NULL, 0, and 1.
EDIT:
I'm trying to understand the logic. Adapted for the right names:
SELECT *
from sample
where (#flgparam = 0 and flgRequired is not null) or
(coalesce(#flgparam, 1) = 1 and flgRequired = 1)
The like is unnecessary; you can do strict equality.
A bit rough, but it should work, based on requirements:
select
S.itemname
,S.flgrequired
from
sample S
where
(S.flgRequired >= #flgParam)
Tested on sqlfiddle.
You cant use variables to substitute columns in the querys, to achieve that you should create your query as a string #QUERY and execute it using exec #QUERY

Select statement which joins to a another table with where definitions inside

I have a table which contains the where selection. For example ExpressionTable:
ID WhereCase
------------------
1 = 4
2 in(2,3)
3 = 3
4 in(4,5,6)
Now I need to select from another table with this WhereCase.
Select * from tablexy join ExpressionTable as et on tablexy.ID = et.ID
Where Country (this (WhereCase) from the ExpressionTable)
When I write where Country = et.WhereCase is not working...
What is the best way for this?
What is the best way for this...
Don't do it.
Based on the example expressions you have provided you can easily store this information in a relational format that can then be joined onto (or appended onto the query with an EXISTS clause to keep the same semantics with respect to Duplicates).
CREATE TABLE XyCountries
(
XyID INT,
Country INT
);
INSERT INTO XyCountries
VALUES (1,4),
(2,2),
(2,3),
(3,3),
(4,4),
(4,5),
(4,6);
you cant have dynamic query conditions.
The only way to achieve what you want is to use dynamic SQL where you build your query in a string and them execute it like EXEC ('select 1')
You will need to build a SQL statement using Dynamic SQL and then execute it, eg
DECLARE #SQL VARCHAR(MAX)
SELECT #SQL = 'Select * from tablexy Where Country ' + et.WhereCase FROM ExpressionTable WHERE ID = ?
Then execute:
EXEC(#SQL)

Find whole value without using LIKE operator

I have a large number to find in a table. But only a little part of it is given to me to find the whole number. I am looking for some new way to find these out without using the like operator. I know it is a simple thing, but I need a new approach.
Value given is: 4213076600
Value to find is: 89013106904213076600
I want to find it in the following query:
SELECT *
FROM table_name
WHERE column_name in (value,value,value)
i have searched the websites for this and came to know about the left() and right() functions but don't know how to arrange them to get the result
You can use CONTAINS more info:
SELECT *
FROM table_name
WHERE CONTAINS(column_name , '"*value*"')
For CONTAINS you need to create a FULL TEXT INDEX on the table.
DECLARE #table table (n varchar(20))
DECLARE #param1 varchar(20)
SET #param1 = '4213076600'
INSERT INTO #table (n)
SELECT '89013106904213076600'
SELECT n
FROM #table
WHERE RIGHT(n, len(#param1)) = #param1
Edit
select *
from table_name
where right(column_name, len(value)) = value
SELECT
*
FROM
table_name
WHERE
CHARINDEX(value1,column_name)>0
OR CHARINDEX(value2,column_name)>0
OR CHARINDEX(value3,column_name)>0
SELECT left(column_name,length_of_value)
FROM table_name
WHERE RIGHT(column_name,length_of_value_given) IN (value,value,value)
That's way it works for IN clause

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.