I have a procedure like this;
SET #Oldname = (SELECT name
FROM [Marketing].[dbo].[_Users]
WHERE ID = #MID);
Everything is okay but some members got xxx, xxx_A1,xxx_A2,xxx_A3, while selecting these members I want to select without _A1 , _A2 , A_30
How can I select it?
Try reversing string, find first index of _ and apply substring:
DECLARE #s NVARCHAR(MAX) = 'John_Smith_234'
DECLARE #t TABLE ( Name NVARCHAR(50) )
INSERT INTO #t
VALUES ( 'John_Smith_234' ),
( 'Michael_Jordan' ),
( 'Honore_De_Balzak_234' )
SELECT SUBSTRING(Name, 1, LEN(Name) - CHARINDEX('_', REVERSE(Name))) AS Name
FROM #t
Output:
Name
John_Smith
Michael
Honore_De_Balzak
try this
select left(name, len(name)-charindex('_', reverse(name))) name
from whatever
Assure that you add a '%' sign to your #MID Variable, looking like 'xxx%'
Than SELECT with LIKE instead of = :
SET #Oldname = (SELECT name From [Marketing].[dbo].[_Users] Where ID LIKE #MID);
I think you may also add the '%' sign in qour query (haven't tried):
SET #Oldname = (SELECT name From [Marketing].[dbo].[_Users] Where ID LIKE #MID+'%');
Related
I am working on a query that I need to modify so that a string is passed to in(). The view table is being used by some other view table and ultimately by a stored procedure. The string values must be in ' '.
select region, county, name
from vw_main
where state - 'MD'
and building_id in ('101', '102') -- pass the string into in()
The values for the building_id will be entered at the stored procedure level upon its execution.
Please check below scripts which will give you answer.
Way 1: Split CSV value using XML and directly use select query in where condition
DECLARE #StrBuildingIDs VARCHAR(1000)
SET #StrBuildingIDs = '101,102'
SELECT
vm.region,
vm.county,
vm.name
FROM vw_main vm
WHERE vm.state = 'MD'
AND vm.building_id IN
(
SELECT
l.value('.','VARCHAR(20)') AS Building_Id
FROM
(
SELECT CAST('<a>' + REPLACE(#StrBuildingIDs,',','</a><a>') + '</a>') AS BuildIDXML
) x
CROSS APPLY x.BuildIDXML.nodes('a') Split(l)
)
Way 2: Split CSV value using XML, Create Variable Table and use that in where condition
DECLARE #StrBuildingIDs VARCHAR(1000)
SET #StrBuildingIDs = '101,102'
DECLARE #TblBuildingID TABLE(BuildingId INT)
INSERT INTO #TblBuildingID(BuildingId)
SELECT
l.value('.','VARCHAR(20)') AS Building_Id
FROM
(
SELECT CAST('<a>' + REPLACE(#StrBuildingIDs,',','</a><a>') + '</a>') AS BuildIDXML
) x
CROSS APPLY x.BuildIDXML.nodes('a') Split(l)
SELECT
vm.region,
vm.county,
vm.name
FROM vw_main AS vm
WHERE vm.state = 'MD'
AND vm.building_id IN
(
SELECT
BuildingId
FROM #TblBuildingID
)
Way 3: Split CSV value using XML, Create Variable Table and use that in INNER JOIN
Assuming the input string is not end-user input, you can do this. That is, derived or pulled from another table or other controlled source.
DECLARE #in nvarchar(some length) = N'''a'',''b'',''c'''
declare #stmt nvarchar(4000) = N'
select region, county, name
from vw_main
where state = ''MD''
and building_id in ({instr})'
set #stmt = replace(#stmt, N'{instr}', #instr)
exec sp_executesql #stmt=#stmt;
If the input is from an end-user, this is safer:
declare # table (a int, b char)
insert into #(a, b) values (1,'A'), (2, 'B')
declare #str varchar(50) = 'A,B'
select t.* from # t
join (select * from string_split(#str, ',')) s(b)
on t.b = s.b
You may like it better anyway, since there's no dynamic sql involved. However you must be running SQL Server 2016 or higher.
I have a dataset with one of the columns as Transaction_Date in which date varies from the year 2005 to 2018.
I need to assign a distinct year to a variable, later on, I will be using the same variable in SQL Pivot.
-- variable declaration
DECLARE #PCOL VARCHAR(20);
-- assigning values to the variable
SELECT #PCOL += (QUOTENAME (X.TD) + ',')
FROM
(
SELECT DISTINCT YEAR(TRANSACTION_DATE) AS TD
FROM TRANSACTION_INFO
) AS X;
-- Check the result
PRINT #PCOL
It is not resulting me the output as expected. Please suggest.
You need FOR XML PATH() clause :
SELECT #PCOL = STUFF( (SELECT DISTINCT ', '+ QUOTENAME(CAST(YEAR(TRANSACTION_DATE) AS VARCHAR(255)))
FROM TRANSACTION_INFO
FOR XML PATH('')
), 1, 1, ''
)
You're getting NULL because you didn't pre-set your variable to an empty string before you used the += operator.
Since NULL + 'some value' = NULL, your variable never gets changed from NULL to something else.
It looks like this is what you're attempting to do...
IF OBJECT_ID('tempdb..#TRANSACTION_INFO', 'U') IS NOT NULL
BEGIN DROP TABLE #TRANSACTION_INFO; END;
CREATE TABLE #TRANSACTION_INFO (
TRANSACTION_DATE DATE
);
INSERT #TRANSACTION_INFO (TRANSACTION_DATE) VALUES
('20130101'),('20130101'),('20140101'),
('20140102'),('20150102'),('20150102'),
('20160103'),('20160103'),('20170104'),
('20170104'),('20180105'),('20180105');
--================================================
DECLARE #POL VARCHAR(200) = '';
SELECT
#POL = CONCAT(#POL, ',', x.TD)
FROM (
SELECT DISTINCT
TD = YEAR(ti.TRANSACTION_DATE)
FROM
#TRANSACTION_INFO ti
) x;
SET #POL = STUFF(#POL, 1, 1, '');
PRINT(#POL);
Result:
2013,2014,2015,2016,2017,2018
How I can select
"ALT1" if value is "W61N03D20V0-WHIH-ALT1"
"ALT2" if for "W61N03D20V0-WHIH-ALT2"
"SW" for "W61N03D20V0-WHIH-SW"
"Default" for "W61N26D1YA1-VICU" (without prefix)
"Defailt" for "W61N27D21V2-AZTD"
In other words I'm looking for a way extract last part after second suffix, but if I have't second suffix - then default
Thanks for advice
Try it like this:
First you "split" the string on its minus signs with the XML trick.
Then you read the third node from you XML - voila!
CREATE TABLE #tbl(content VARCHAR(100));
INSERT INTO #tbl VALUES('W61N03D20V0-WHIH-ALT1')
,('W61N03D20V0-WHIH-SW')
,('W61N26D1YA1-VICU');
WITH SplittedAsXml AS
(
SELECT CAST('<x>' + REPLACE(content,'-','</x><x>') + '</x>' AS XML) AS Content
FROM #tbl
)
SELECT ISNULL(Content.value('/x[3]','varchar(max)'),'default') AS TheThirdPart
FROM SplittedAsXml;
DROP TABLE #tbl;
The result
ALT1
SW
default
Going this ways would also give you the chance to get the other parts in one go just querying /x[1] and /x[2] too
I did it using the built-in substring() function:
declare #str VARCHAR(40) = 'W61N03D20V0-WHIH-ALT1' -- also works for the other examples
declare #sep VARCHAR(1) = '-'
declare #middleToEnd VARCHAR(40) = substring(#str, charindex(#sep, #str) + 1, len(#str))
declare #pos INT = charindex(#sep, #middleToEnd)
declare #lastPart VARCHAR(40) =
CASE WHEN #pos = 0
THEN 'Default'
ELSE substring(#middleToEnd, #pos + 1, len(#middleToEnd))
END
select #lastPart
For best performance, you can solve it with this one-liner(calculation is one line)
SELECT
COALESCE(STUFF(col,1,NULLIF(CHARINDEX('-',col, CHARINDEX('-',col)+1), 0),''),'Default')
FROM (values
('W61N03D20V0-WHIH-ALT1'),('W61N03D20V0-WHIH-ALT2'),
('W61N03D20V0-WHIH-SW'),('W61N26D1YA1-VICU'),
('W61N27D21V2-AZTD')) x(col)
Result:
ALT1
ALT2
SW
Default
Default
If I understand what you are asking for, the following does what you need:
-- fake table
WITH SomeTable AS (
SELECT 'W61N03D20V0-WHIH-ALT1' AS Field1
UNION ALL
SELECT 'W61N03D20V0-WHIH-SW'
UNION ALL
SELECT 'W61N26D1YA1-VICU'
)
-- select
SELECT
CASE CHARINDEX('-WHIH-', Field1)
WHEN 0 THEN 'Default'
ELSE SUBSTRING(Field1, CHARINDEX('-WHIH-', Field1) + 6, LEN(Field1) - (CHARINDEX('-WHIH-', Field1) + 5))
END
FROM SomeTable
Use can use a CASE expression to check whether the string starts with W61N03D20V0-WHIH.
If it starts with it use a combination of RIGHT, REVERSE and CHARINDEX functions to get last part from the string, else Default.
Query
select case when [your_column_name] like 'W61N03D20V0-WHIH%'
then right([your_column_name], charindex('-', reverse([your_column_name]), 1) - 1)
else 'Default' end as new_column_name
from your_table_name;
SQl Fiddle demo
I have two type of strings in a column.
DECLARE #t table(parameter varchar(100))
INSERT #t values
('It contains eact01' ),
('It contains preact01')
I'm trying to get the strings that contain the word 'eact01'.
My problem is that using the following SELECT, I get also the variables that contain 'preact01', because it contain 'eact01'.
SELECT * FROM #t WHERE parameter LIKE '%eact01%'
How could I get only the row containing 'eact01'?
This should find all combinations, any character not being a letter or a number considerer this as a spit character or a new word.
SELECT *
FROM #t
WHERE
parameter like '%[^0-9a-z]eact01'
or parameter like '%[^0-9a-z]eact01[^0-9a-z]%'
or parameter like 'eact01[^0-9a-z]%'
or parameter = 'eact01'
Try this-
select *
from #t
where
parameter='eact01'
OR parameter like '%[^0-9a-z]eact01%'
OR parameter like 'eact01[^0-9a-z]%'
OR parameter like '%[^0-9a-z]eact01[^0-9a-z]%'
The easiest way is just add space:
SELECT * FROM #t WHERE parameter LIKE '% eact01%' or parameter LIKE 'eact01%'
You need a string splitter for this. Here is one taken from Aaron Bertrand's article:
CREATE FUNCTION dbo.SplitStrings_XML
(
#List NVARCHAR(MAX),
#Delimiter NVARCHAR(255)
)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN
(
SELECT Item = y.i.value('(./text())[1]', 'nvarchar(4000)')
FROM
(
SELECT x = CONVERT(XML, '<i>'
+ REPLACE(#List, #Delimiter, '</i><i>')
+ '</i>').query('.')
) AS a CROSS APPLY x.nodes('i') AS y(i)
);
Then, you can use EXISTS:
SELECT *
FROM #t
WHERE EXISTS(
SELECT 1
FROM dbo.SplitStrings_XML(parameter, ' ') s
WHERE s.Item = 'eact01'
)
I currently have the following select statement, but I wish to move to full text search on the Keywords column. How would I re-write this to use CONTAINS?
SELECT MediaID, 50 AS Weighting
FROM Media m JOIN #words w ON m.Keywords LIKE '%' + w.Word + '%'
#words is a table variable filled with words I wish to look for:
DECLARE #words TABLE(Word NVARCHAR(512) NOT NULL);
If you are not against using a temp table, and EXEC (and I realize that is a big if), you could do the following:
DECLARE #KeywordList VARCHAR(MAX), #KeywordQuery VARCHAR(MAX)
SELECT #KeywordList = STUFF ((
SELECT '"' + Keyword + '" OR '
FROM FTS_Keywords
FOR XML PATH('')
), 1, 0, '')
SELECT #KeywordList = SUBSTRING(#KeywordList, 0, LEN(#KeywordList) - 2)
SELECT #KeywordQuery = 'SELECT RecordID, Document FROM FTS_Demo_2 WHERE CONTAINS(Document, ''' + #KeywordList +''')'
--SELECT #KeywordList, #KeywordQuery
CREATE TABLE #Results (RecordID INT, Document NVARCHAR(MAX))
INSERT INTO #Results (RecordID, Document)
EXEC(#KeywordQuery)
SELECT * FROM #Results
DROP TABLE #Results
This would generate a query like:
SELECT RecordID
,Document
FROM FTS_Demo_2
WHERE CONTAINS(Document, '"red" OR "green" OR "blue"')
And results like this:
RecordID Document
1 one two blue
2 three red five
If CONTAINS allows a variable or column, you could have used something like this.
SELECT MediaID, 50 AS Weighting
FROM Media m
JOIN #words w ON CONTAINS(m.Keywords, w.word)
However, according to Books Online for SQL Server CONTAINS, it is not supported. Therefore, no there is no way to do it.
Ref: (column_name appears only in the first param to CONTAINS)
CONTAINS
( { column_name | ( column_list ) | * }
,'<contains_search_condition>'
[ , LANGUAGE language_term ]
)