If clause in sql - sql-server

Declare #a varchar(100);
If #a = select productname from product
The above mentioned query is throwing error as my sql query (select product name from product) is returning multiple values.
Can someone help me with this?

Try something like:
Declare #a varchar(100);
SELECT #a = 'MyProduct'
Then either
If #a = select TOP 1 productname from product ORDER BY <some field>
OR
If #a IN (select productname from product)
However, how do you know which product(s) to match to; you might need a WHERE clause. Some sample data and desired results would help.

Please note that you need to put the SELECT query inside the parenthesis in this case! Also you should note that your select query, in this case should not return more than one value. So to resolve these you need to write it as:
Declare #a varchar(100);
If #a = (select TOP 1 productname from product)
However your query logically seems to be invalid and you should rethink about it, for example you need to say that, you are going to check #a with which product? You might need to add some filters to query and/or add ELSE to your if, etc.
You might also need to read the #PeterSmith's answer too(Using IN...)

Related

Manipulate a string to be used in IN operator (SQL, SSRS)

I have an SSRS report with dataset that has query looking like this (simplified as the query is a lot more complex that this):
select *
from myTable
where country in (#Country)
#Country is a parameter and can have multiple values
It works fine, but we were asked to roll up all the values from one country to another one (the country is not in the list of parameters to be selected).
So for example we need to roll up all the records that belong to Canada to US if US was selected as one of the Countries essentially just replacing 'Canada' with 'US' in the dataset returned which is easy to achieve using REPLACE or even CASE statement. However, it gets a bit tricky with WHERE clause in the query. Does anyone know how to replace a string with another string so it's understood by IN operator?
If I simply do something like this:
select *
from myTable
where country in (replace(#Country, 'US', 'US,Canada'))
the query doesn't return anything and I understand the reasons behind it.
If I test this hardcoding the values like this:
select *
from myTable
where country in ('US', 'Canada')
it returns the correct rows of data. I think I'm looking for a way to join multiple values so it's understood properly by IN operator.
TIA,
-TS.
You can use Dynamic SQL to achieve this. All you need to do is pass country name in declaration at first line.
Look at the code below:
DECLARE #SQL NVARCHAR(2000), #Country VARCHAR(30) = 'Canada'
SELECT #SQL = CONCAT('
select
*
from myTable
where country in (',
CASE WHEN #Country = 'US' THEN '''US'', ''Canada''' else '#Country' end , ')'
)
EXEC sp_executesql #SQL, N'#Country VARCHAR(30)', #Country = #Country
Here's a fiddle : http://sqlfiddle.com/#!18/b7f49/4
Possibly the same answer as SQL in (#Variable) query
You may need to add REPLACE to that function based on your requirements.

SQL Server Select into variable not null when expected to be null (info)

This is not a question but rather some SQL Server information I recently learned that was driving me crazy. I'm sure plenty of others (most?) here already know it, but just in case, maybe it will save someone hours of debugging. Take this example:
create table test1 (field1 varchar(16), field2 int);
insert into test1 values ('helloworld', 1);
declare #field2 int;
select #field2 = field2 from test1 where field1 = 'helloworld';
select #field2 'firstTime';
select #field2 = field2 from test1 where field1 = 'worldhello';
select #field2 'secondTime';
I expected secondTime to be null because the row was not found. But in fact it carried over from the previous select! You would need to either use if exists or set #field2=null before the second select.
Like I said, most of you probably already know this, but maybe it will help someone.
As was suggested by a commenter the correct way is to use something like:
SET #field2 = (SELECT field2 FROM test1 WHERE field1 = 'worldhello');
See other comments for explanations.

SQL Query Results to Local Variable without unique identifier

I'm relatively new to SQL and I'm trying to write a query that will assign the result of multiple rows into a local variable
DECLARE #x VARCHAR(MAX)
SET #x= (SELECT someCol
FROM table)
--Does important stuff to the #x variable
SELECT #x
During my research I realized that this won't work because the subquery can only return one value and my query will return multiple results. However I can not do something like this:
DECLARE #x VARCHAR(MAX)
SET #x= (SELECT someCol
FROM table
where id= 'uniqueIdentifier')
--Does important stuff to the #x variable
SELECT #x
The reason I can't use a where clause is that I need to do this for the entire table and not just one row. Any ideas?
EDIT: I realized my question was too broad so I'll try to reformat the code to give some context
SELECT col_ID, col_Definition
FROM myTable
If I were to run this query col_Definition would return a large varchar which holds a lot of information such as the primary key of another table that I'm trying to obtain. Lets say for example I did:
DECLARE #x VARCHAR(MAX)
SET #x= (SELECT col_Definition
FROM myTable
WHERE col_ID = 1)
--Function to do the filtering of the varchar variable that works as expected
SELECT #x as [Pk of another table] --returns filtered col_Definition
This will work as expected because it returns a single row. However, I would like to be able to run this query so that it will return the filtered varchar for every single row in the "myTable" table.
If I understand correctly, you store a PK embedded in a string that you want to eventually get out and use to join to that table. I would think putting the group of records you want to work with into a temp table and then applying some logic to that varchar column to get the PK. That logic is best as set based, but if you really want row by row, use a scalar function rather than a variable and apply it to the temp table:
select pk_column, dbo.scalarfunction(pk_column) as RowByRowWithFunction, substring(pk_column,5,10) as SetBasedMuchFaster
from #tempTable.
You need to define what the 'uniqueIdentifier' is first.
Not sure about using a subquery and grabbing the result and executing another query with that result unless you do an INNER JOIN of some sort or if using python or another language to process the data then use:
("SELECT someCol
FROM table
where id='%s'" % Id)

SQL Select value as (Subquery)

This is the query I am trying to get to work, but I'm getting a syntax error.
SELECT Column1 as (SELECT Value2 from Table2 Where ConditionA, ConditionB, ConditionC)
from Table1
I am self taught, and haven't found anything that says explicitly that this can't be done, but if that is the case then thanks for the closure.
You cannot use the value returned from a subquery for an alias, there is no way to make that work.
Your only option is to build the sql dynamically, and use sp_executesql, but thats usually an indication something else has gone wrong!
Start by getting the value you want, a couple of points
ensure you only get 1 result, either using TOP 1 or appropriate filter conditions
multiple conditions are separated with AND or OR, not a comma
declare #alias NVARCHAR(100) -- whatever is appropriate
SELECT TOP 1 #alias = value2 FROM Table2
WHERE someField = 'some value'
Then build up the sql dynamically, and execute it.
DECLARE #sql NVARCHAR(100) = 'SELECT Column1 AS ' + #alias + ' FROM Table1'
EXEC sp_executesql #sql
You can see this in action here: http://sqlfiddle.com/#!3/71f8d6/3
But, I stress, this is a bad solution.
try
SELECT (SELECT Value2 from Table2 Where ConditionA, ConditionB, ConditionC) Column1 from Table1

Use SELECT result for another query

Is there any way other than using a cursor that I can use SELECT results for a subsequent INSERT/UPDATE query?
Something like:
DECLARE #SELECTRESULT;
SELECT Something into #SELECTRESULT
FROM Somewhere
INSERT INTO SomewhereElse (X, XX, XXX)
SELECT Something, GETDATE(), 'XXX'
FROM #SELECTRESULT
UPDATE Somewhere
Set SomethingElse = 'ABC'
WHERE
Something in
(SELECT Something FROM #SELECTRESULT)
The reason is that I have a relatively complex query from multiple tables and I don't want duplicate this code, once for the insert and second time for the update.
You can use a table variable.
Something like
DECLARE #Table TABLE(
Col1 INT
)
INSERT INTO #Table
SELECT Col1
FROM Table
Have a look at
Table Variables In T-SQL
DECLARE #local_variable (Transact-SQL)
Just use a temporary table it's ok for your case :
SELECT Something into #temporary_table FROM Somewhere WHERE blabla
use a temp table.
CREATE TABLE #tempTable
(
Something int NOT NULL,
CurrentDate DateTime NULL,
XXX Varchar(50)
)
Then use your complex query on multiple tables and insert the result set into the tempTable.
Insert into #tempTable
-- Complex Select Query
Just make sure that the columns returned by the selected query match in the order as per the #tempTable structure. Also the number of columns should match.
Once you have #tempTable with the complex data, you can use it multiple number of times for insert and update queries.
INSERT INTO SomewhereElse (X, XX, XXX)
SELECT * from #tempTable
UPDATE Somewhere
Set SomethingElse = 'ABC'
WHERE
Something in (SELECT Something FROM #tempTable)
DECLARE #SELECTRESULT table(Something nvarchar(50)) --the data that you could reuse.
insert into #SELECTRESULT(Something)
SELECT Something
FROM Somewhere
INSERT INTO SomewhereElse (X, XX, XXX)
SELECT Something, GETDATE(), 'XXX'
FROM #SELECTRESULT
UPDATE Somewhere
Set SomethingElse = 'ABC'
WHERE Something in
(SELECT Something FROM #SELECTRESULT)

Resources