SQL Server WHERE with wildcard - sql-server

Is it possible to use a wildcard for the where in statement in SQL Server 2008?
For example, I currently have:
SELECT something
FROM myTable
WHERE (ORG + '-' + ORGSUB like '5015001-________' or
ORG + '-' + ORGSUB like '5015018-________' or
ORG + '-' + ORGSUB like '_______-________')
I need to do it this way:
SELECT something
FROM myTable
WHERE
(ORG + '-' + ORGSUB) in( '5015001-________','5015018-________','_______-________')
i'm going to be passing those values through a stored procedure as a comma delimited list. is there another way to get it done?

Take your comma delimited list, split it, and insert it into a temp table...
You can then use a LIKE statement in a JOIN to this temp table:
SELECT something
FROM myTable mt
JOIN #tempTable tt
ON mt.ORG + '-' + mt.ORGSUB LIKE tt.SearchValue

Why do you even care about ORGSUB in your query (as provided in the example)?
Seems to me you should rewrite your WHERE clause to look for the components separately, e.g.:
SELECT something
FROM myTable
WHERE ORG IN (5015001, 5015018, ...)
[add other criteria as appropriate]

Why a comma-separated list?
DECLARE TYPE dbo.OrgSub AS TABLE(s VARCHAR(32));
GO
CREATE PROCEDURE dbo.SearchOrgSubs
#OrgSub dbo.OrgSub READONLY
AS
BEGIN
SET NOCOUNT ON;
SELECT t.something
FROM dbo.mytable AS t
INNER JOIN #OrgSub AS o
ON t.ORG + '-' + t.ORGSUB = o.s;
END
GO
Now you can pass the set into the stored procedure from C# or wherever, without first having to form it into a comma-separated list.

You can create a temp Table contains the result of a split function.
SELECT somthing
from myTable
JOIN dbo.Split('5015001-________','5015018-________','_______-________') as Splits
on (ORG + '-' + ORGSUB) like Splits.items

Related

Add GO separator for insert statements in long script

I have a table with a couple of thousand rows. For simplicity I assume it has one column. I need to generate insert statements so I can run that somewhere else.
I use this query:
select
'insert into #ids values (' + cast(ID as varchar) + ')' as SqlStr
from MySourceTable
This generates the insert statements but when I run this I get error that cannot run more than 1000 rows in a batch.
Now I'm trying to add GO on every 1000th rows but I don't want to do that manually.
How can I change my query to add GO after every 1000th row?
You can add GO after every 1000th row using below query
;with ct as (
select 'insert into #ids values (' + cast(ID as varchar) + ')' as SqlStr
, row_number() over (order by LoanNum) as RN
from MySourceTable
)
select iif(RN % 1000 = 0, SqlStr + char(10) + 'go' + char(10), SqlStr)
from ct
This simply adds a line-feed to generated statement.
Note that you need to switch the result to TEXT to be able to get the correct output

SQL Server Regular expression extract pattern from DB colomn

I have a question about SQL Server: I have a database column with a pattern which is like this:
up to 10 digits
then a comma
up to 10 digits
then a semicolon
e.g.
100000161, 100000031; 100000243, 100000021;
100000161, 100000031; 100000243, 100000021;
and I want to extract within the pattern the first digits (up to 10) (1.) and then a semicolon (4.)
(or, in other words, remove everything from the semicolon to the next semicolon)
100000161; 100000243; 100000161; 100000243;
Can you please advice me how to establish this in SQL Server? Im not very familiar with regex and therefore have no clue how to fix this.
Thanks,
Alex
Try this
Declare #Sql Table (SqlCol nvarchar(max))
INSERT INTO #Sql
SELECT'100000161,100000031;100000243,100000021;100000161,100000031;100000243,100000021;'
;WITH cte
AS (SELECT Row_number()
OVER(
ORDER BY (SELECT NULL)) AS Rno,
split.a.value('.', 'VARCHAR(1000)') AS Data
FROM (SELECT Cast('<S>'
+ Replace( Replace(sqlcol, ';', ','), ',',
'</S><S>')
+ '</S>'AS XML) AS Data
FROM #Sql)AS A
CROSS apply data.nodes('/S') AS Split(a))
SELECT Stuff((SELECT '; ' + data
FROM cte
WHERE rno%2 <> 0
AND data <> ''
FOR xml path ('')), 1, 2, '') AS ExpectedData
ExpectedData
-------------
100000161; 100000243; 100000161; 100000243
I believe this will get you what you are after as long as that pattern truly holds. If not it's fairly easy to ensure it does conform to that pattern and then apply this
Select Substring(TargetCol, 1, 10) + ';' From TargetTable
You can take advantage of SQL Server's XML support to convert the input string into an XML value and query it with XQuery and XPath expressions.
For example, the following query will replace each ; with </b><a> and each , to </a><b> to turn each string into <a>100000161</a><a>100000243</a><a />. After that, you can select individual <a> nodes with /a[1], /a[2] :
declare #table table (it nvarchar(200))
insert into #table values
('100000161, 100000031; 100000243, 100000021;'),
('100000161, 100000031; 100000243, 100000021;')
select
xCol.value('/a[1]','nvarchar(200)'),
xCol.value('/a[2]','nvarchar(200)')
from (
select convert(xml, '<a>'
+ replace(replace(replace(it,';','</b><a>'),',','</a><b>'),' ','')
+ '</a>')
.query('a') as xCol
from #table) as tmp
-------------------------
A1 A2
100000161 100000243
100000161 100000243
value extracts a single value from an XML field. nodes returns a table of nodes that match the XPath expression. The following query will return all "keys" :
select
a.value('.','nvarchar(200)')
from (
select convert(xml, '<a>'
+ replace(replace(replace(it,';','</b><a>'),',','</a><b>'),' ','')
+ '</a>')
.query('a') as xCol
from #table) as tmp
cross apply xCol.nodes('a') as y(a)
where a.value('.','nvarchar(200)')<>''
------------
100000161
100000243
100000161
100000243
With 200K rows of data though, I'd seriously consider transforming the data when loading it and storing it in indivisual, indexable columns, or add a separate, related table. Applying string manipulation functions on a column means that the server can't use any covering indexes to speed up queries.
If that's not possible (why?) I'd consider at least adding a separate XML-typed column that would contain the same data in XML form, to allow the creation of an XML index.

SQL to split Comma Separated values and compare it with a multi list value in SSRS

I have a field in my table which has multiple reason codes concatenated in 1 column.
e.g. 2 records
Reason_Codes
Record1: 001,002,004,009,010
Record2: 001,003,005,006
In my SSRS report the user will be searching for data using one of the above reason codes. e.g.
001 will retrieve both records.
005 will retrieve the second record
and so on.
Kindly advise how this can be achieved using SQL or Stored Procedure.
Many thanks.
If you are just passing in a single Reason Code to search on, you don't even need to bother with splitting the comma-separated list: you can just use a LIKE clause as follows:
SELECT tb.field1, tb.field2
FROM SchemaName.TableName tb
WHERE ',' + tb.Reason_Codes + ',' LIKE '%,' + #ReasonCode + ',%';
Try the following to see:
DECLARE #Bob TABLE (ID INT IDENTITY(1, 1) NOT NULL, ReasonCodes VARCHAR(50));
INSERT INTO #Bob (ReasonCodes) VALUES ('001,002,004,009,010');
INSERT INTO #Bob (ReasonCodes) VALUES ('001,003,005,006');
DECLARE #ReasonCode VARCHAR(5);
SET #ReasonCode = '001';
SELECT tb.ID, tb.ReasonCodes
FROM #Bob tb
WHERE ',' + tb.ReasonCodes + ',' LIKE '%,' + #ReasonCode + ',%';
-- returns both rows
SET #ReasonCode = '005';
SELECT tb.ID, tb.ReasonCodes
FROM #Bob tb
WHERE ',' + tb.ReasonCodes + ',' LIKE '%,' + #ReasonCode + ',%';
-- returns only row #2
I have blogged about something like this a long time ago. May be this will help: http://dotnetinternal.blogspot.com/2013/10/comma-separated-to-temp-table.html
The core solution would be to convert the comma separated values into a temporary table and then do a simple query on the temporary table to get your desired result.

How can I fit this UPDATE query into this existing SELECT statement?

I have an existing stored procedure. I have been asked to attempt to find a way to fit a specific set of logic into the procedure in order to avoid having to create a new one. However, I am not the best with SQL, but I would still like to do everything I can to accomplish my task.
My current goal: use the existing table generated from the select top 400 statement and somehow fit the update I wrote (second chunk of code) to work with that.
My existing procedure:
USE [cph]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER proc [dbo].[PatientSynch]
#EnvironmentKey varchar(1)
AS
BEGIN
DECLARE #patId VARCHAR(25)
select top 400
c.pat_id as cpPatId,
(LEFT(c.fname, 1)
+LEFT(c.lname, 1)
+ #EnvironmentKey
+ RIGHT('00000000'
+ convert(varchar,c.pat_id),8 )) AS PRN,
c.pref_meth_cont_cn as PreferredChannel
--,p.cppatid,p.prn
from
dbo.cppat c
left outer join dbo.patient p on c.pat_id=p.cppatid
where
p.cppatid is null or p.prn is null
order by
c.pat_id desc
END
The statement I have created to suit my needs:
UPDATE dbo.cppat
SET chart_id = CONVERT(VARCHAR(10), pat_id) + '+'
WHERE pat_id IN
(
SELECT pat_id
FROM cppat
)
I've added Chart_id in the query since you need it there to update it. This creates a common table expression that you can use to update records.
;WITH Update_Complex_Query AS
(
SELECT TOP 400
c.pat_id AS cpPatId
, (LEFT(c.fname, 1) + LEFT(c.lname, 1) + #EnvironmentKey + + RIGHT('00000000' + convert(VARCHAR, c.pat_id), 8)) AS PRN
, c.pref_meth_cont_cn AS PreferredChannel
--,p.cppatid,p.prn
, c.Chart_Id
FROM dbo.cppat c
LEFT JOIN dbo.patient p
ON c.pat_id = p.cppatid
WHERE p.cppatid IS NULL
OR p.prn IS NULL
ORDER BY c.pat_id DESC
)
UPDATE Update_Complex_Query
SET Chart_id = CONVERT(VARCHAR(10), cpPatId) + '+'

Dynamic Stored Procedure Results to Table

I have a stored procedure that dynamically produces pivot results, passing sql for row defs, column to pivot, aggregate(field) to sum, and table name of aggregate. This works great, but i need to produce a table from these results to use in further calculations.
How can I dynamically save the results to a table within the stored procedure (temp or non temp) without knowing the output columns??
SELECT *
INTO #TempTable
FROM (Pivot Expression)
This will create a #TempTable with the results of whatever you have in the FROM clause, regardless of number/type of columns.
you didn't ask, but this is how I'm getting a set of column names from a view:
DECLARE #columns VARCHAR(1000)
SELECT #columns = COALESCE(#columns + ',[' + cast(fld as varchar) + ']',
'[' + cast(fld as varchar)+ ']')
FROM view
GROUP BY fld

Resources