Anything like template literals while writing a search query in SQL? - sql

I am writing a stored procedure to get a particular value.
declare #num int
set #num = (SELECT Id
FROM [sometable]
WHERE Name like '%today%')
-- returns #num = 1
Select Value
FROM [anothertable]
where name like 'days1'
In the last line of the query I want to add "1" or any other number after 'days', depending on the variable #num.
How can I do it, sort of like how we use template literals in Javascript, using the ${} syntax but in SQL?

You can just use the first query as a sub-query of the second:
select [Value]
from anothertable
where [name] = Concat('days', (select Id from sometable where [Name] like '%today%'));

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.

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

Replace Any Occurrence of "P" in String With A Value From Another Table

I have a column, sort_order in a table that contains a string of numbers, a delimiter and some P values:
1150||P||1168||1144||1149||1147||1164||1152||P||1148||1162||1163||P||1156||1157||1154||
I would like to replace any P values in this string with another value from the event_tile_id column of another table.
So far I've drafted this SQL below with no luck. What changes can I make to this Query to get the effect I need?
`SELECT sort_order,
(
REPLACE(sort_order,'P',
(SELECT TOP 1 event_tile_id
FROM daily_email_sales_today)
)
)
as sort_order
FROM daily_email_preview`
Removed "default_SaleID" from Query. Replace should now have 4 arguments.
This is how I would do it.
Since you don't have any joins, why not do a simpler update query using a static value?
DECLARE #update VARCHAR(100)
SET #update = (SELECT TOP 1 event_tile_id FROM daily_email_sales_today)
update daily_email_preview
SET sort_order = replace(sort_order,'P', #update)
Or even,
update daily_email_preview
SET sort_order = replace(sort_order,'P', '<new value>')
Assuming you are using SQL Server.
Along the same thought process as #Eric_Hauenstein if you are running this in a TSQL process:
declare #rSTR as varchar(50)
SELECT TOP 1 #rSTR = event_tile_id FROM daily_email_sales_toda
SELECT sort_order, REPLACE(sort_order,'P', #rSTR) as sort_order
FROM daily_email_preview

Using a string of quoted values in a variable for a SQL WHERE CLAUSE

The answer escapes me...maybe because it is not possible...
Example that works...
SELECT * FROM TABLEA WHERE FIELD1 IN ('aaa','bbb','ccc')
Example that does not work...
Attempt to leverage variable so that I can define the values once in a string of statements
DECLARE #ListValues VARCHAR(50)
SET #ListValues = '''aaa'',''bbb'',''ccc'''
SELECT * FROM TABLEA WHERE FIELD1 IN (#ListValues)
This is is obviously only a small part of the equation and for other reasons...
I cannot leverage a table for the values and change this to a true sub-query
The closest question I could find was this one... but does not cover my requirements obviously...
Storing single quotes in varchar variable SQL Server 2008
Thanks in advance.
You can do this using dynamic SQL:
DECLARE #ListValues VARCHAR(MAX)
,#SQL VARCHAR(MAX)
SELECT #ListValues = '''aaa'',''bbb'',''ccc'''
,#SQL = 'SELECT * FROM TABLEA WHERE FIELD1 IN ('+#ListValues+')'
EXEC (#SQL)
It doesn't work because the IN operator expects a list of items - here strings.
What you're supplying with your #ListValues variable however is a single string - not a list of strings.
What you could do is use a table variable and store your values in it:
DECLARE #ListOfValues TABLE (ItemName VARCHAR(50))
INSERT INTO #ListOfValues(ItemName)
VALUES('aaa'), ('bbb'), ('ccc')
SELECT *
FROM TABLEA
WHERE FIELD1 IN (SELECT ItemName FROM #ListOfValues)
Build your whole SQL query dynamically (say it's stored in a string variable #sql),
and then execute it with EXEC (#sql). Better yet, use the sp_executesql SP
because this approach is more secure (less prone to SQL injection) than EXEC.
See: sp_executesql
The IN operator in SQLServer expect a list of values, your variable is a single string, the query parsed will be different
SELECT * FROM TABLEA WHERE FIELD1 IN ('aaa','bbb','ccc')
SELECT * FROM TABLEA WHERE FIELD1 IN ("'aaa','bbb','ccc'")
Attention: the double quotes are there only for readability, to get the string with single quote in it.
if you know a programming language the first one is like searching in an array, the second is a string.
To store a list in your variable it need to a table
DECLARE #varTable TABLE (field1 varchar())
So that you can use it in your IN
SELECT * FROM TABLEA WHERE FIELD1 IN (SELECT field1 FROM #varTable)
To add values to the table variable use an INSERT statament like usual for tables.

SQL: Order randomly when inserting objects to a table

I have an UDF that selects top 6 objects from a table (with a union - code below) and inserts it into another table. (btw SQL 2005)
So I paste the UDF below and what the code does is:
selects objects for a specific city and add a level to those (from table Europe)
union that selection with a selection from the same table for objects that are from the same country and add a level to those
From the union, selection is made to get top 6 objects, order by level, so the objects from the same city will be first, and if there aren't any available, then objects from the same country will be returned from the selection.
And my problem is, that I want to make a random selection to get random objects from table Europe, but because I insert the result of my selection into a table, I can't use order by newid() or rand() function because they are time-dependent, so I get the following errors:
Invalid use of side-effecting or time-dependent operator in 'newid' within a function.
Invalid use of side-effecting or time-dependent operator in 'rand' within a function.
UDF:
ALTER FUNCTION [dbo].[Objects] (#id uniqueidentifier)
RETURNS #objects TABLE
(
ObjectId uniqueidentifier NOT NULL,
InternalId uniqueidentifier NOT NULL
)
AS
BEGIN
declare #city varchar(50)
declare #country int
select #city = city,
#country = country
from Europe
where internalId = #id
insert #objects
select #id, internalId from
(
select distinct top 6 [level], internalId from
(
select top 6 1 as [level], internalId
from Europe N4
where N4.city = #city
and N4.internalId != #id
union select top 6 2 as [level], internalId
from Europe N5
where N5.countryId = #country
and N5.internalId != #id
) as selection_1
order by [level]
) as selection_2
return
END
If you have fresh ideas, please share them with me.
(Just please, don't suggest to order by newid() or to add a column rand() with seed DateTime (by ms or sthg), because that won't work.)
Perhaps you could take advantage of the guids by adding a position parameter to your inputs and then passing in a randomly generated value and then ordering by Substring(internalID, #Random,1)
I found a good solution myself and I thought it might be handy to share it :)
DECLARE #seed1 int
DECLARE #seed2 int
SET #seed1 = DATEPART(SECOND,GETDATE())
SET #seed2 = DATEPART(MILLISECOND,GETDATE())
SELECT TOP 10 [Column1], [Column2]
FROM [TABLE]
ORDER BY ROW_NUMBER() OVER (ORDER BY [KeyColumn]) * seed2 % seed1
I think it's simple enough and it's quite handy
What version of the database server are you using?
In SQL Server 2005 you can use rand with getdate as seed, and the function becomes indeterministic.
In earlier versions you can't have indeterministic functions, and you would have to use a stored procedure instead.