Regex matching the following Input in SQL Column - sql

I have a SQL Column with the following values
ReportID
--------
19
19,20,21
20,19,21
20,21,19
119,21
1191,21
I need to match the the rows which have 19 as a value (i.e. reject last two rows)
Is there a better way to do this than the query used below ? (Using combined regex)
My Query:
SELECT *
FROM [StoreBI_Validation].[dbo].[PortalNotifications]
WHERE ReportID like '%,19,%'
or ReportID like '19'
or ReportID like '19,%'
or ReportID like '%,19'

Try this :
SELECT *
FROM Test
WHERE ','+ReportID+',' like '%,19,%'
SQL Fiddle
Or this :
SELECT DISTINCT reportid
FROM (
SELECT A.ReportID
,Split.a.value('.', 'VARCHAR(100)') AS Data
FROM (
SELECT ReportID
,CAST('<M>' + REPLACE(ReportID, ',', '</M><M>') + '</M>' AS XML) AS Data
FROM Test
) AS A
CROSS APPLY Data.nodes('/M') AS Split(a)
) B
WHERE Data = '19';

SELECT *
FROM [StoreBI_Validation].[dbo].[PortalNotifications]
WHERE CHARINDEX(',19,',ReportID)>0

Related

Create comma separated group list from rows

I need to extract a comma separated list from the following:
Return should gives something like
1 : Route#1, Route#2
2 : Route#3, Route#4
3 : Route#5
4 : Route#6
I'm struggling with the STUFF function. So far I have:SELECT STUFF( (SELECT DISTINCT ';' + T4.[Outbound Trucks] FROM #TEMP4 T4 FOR XML PATH('') ),1,1,'') AS MasterRoutes
Result gives me
any help would be really appreciated.
thanks a lof for your time
If your sql server is 2017 or more :
SELECT dorno, STRING_AGG ([Outbound Trucks], ',') as CSV
FROM #TEMP4
GROUP BY dorno
Explanation Here
In you case you can eliminate doublon to like this:
with tmp as (
select distinct dorno, [Outbound Trucks] Truck from #TEMP4
)
SELECT dorno, STRING_AGG (Truck, ',') as CSV
FROM tmp
GROUP BY dorno

Concatening in a specific order given by a number

I have a table like this:
I want to concatenate the Product name in the given Product_order by ID.
Therefore, I should get something like: CC-TC-CA for ID 1.
you can use string_agg()- it'll work sql server 2016+
select id, string_Agg(product,',') as pname
from tablename
group by id
OR you can use stuff()
SELECT id,
STUFF((SELECT ',' + product
FROM tablename AS T1
WHERE T1.id = T2.id
FOR XML PATH('')), 1, 1, '')
FROM tablename AS T2
GROUP BY id
If you can use a stored procedure instead of a single query the += operator can do what you're looking for.
DECLARE #Product_order VARCHAR(100) = '';
SELECT #Product_order += Product + '-' FROM [table] WHERE id = 1 ORDER BY Product_Order;
SELECT SUBSTRING(#Product_order, 0, LEN(#Product_order));
Update: I've learned that returning multiple rows and using in an assignment in the select clause is unsupported behavior in SQL Server.

How to combine return results of query in one row

I have a table that save personnel code.
When I select from this table I get 3 rows result such as:
2129,3394,3508,3534
2129,3508
4056
I want when create select result combine in one row such as:
2129,3394,3508,3534,2129,3508,4056
or distinct value such as:
2129,3394,3508,3534,4056
You should ideally avoid storing CSV data at all in your tables. That being said, for your first result set we can try using STRING_AGG:
SELECT STRING_AGG(col, ',') AS output
FROM yourTable;
Your second requirement is more tricky, and we can try going through a table to remove duplicates:
WITH cte AS (
SELECT DISTINCT VALUE AS col
FROM yourTable t
CROSS APPLY STRING_SPLIT(t.col, ',')
)
SELECT STRING_AGG(col, ',') WITHIN GROUP (ORDER BY CAST(col AS INT)) AS output
FROM cte;
Demo
I solved this by using STUFF and FOR XML PATH:
SELECT
STUFF((SELECT ',' + US.remain_uncompleted
FROM Table_request US
WHERE exclusive = 0 AND reqact = 1 AND reqend = 0
FOR XML PATH('')), 1, 1, '')
Thank you Tim

Alphanumeric sort on nvarchar(50) column

I am trying to write a query that will return data sorted by an alphanumeric column, Code.
Below is my query:
SELECT *
FROM <<TableName>>
CROSS APPLY (SELECT PATINDEX('[A-Z, a-z][0-9]%', [Code]),
CHARINDEX('', [Code]) ) ca(PatPos, SpacePos)
CROSS APPLY (SELECT CONVERT(INTEGER, CASE WHEN ca.PatPos = 1 THEN
SUBSTRING([Code], 2,ISNULL(NULLIF(ca.SpacePos,0)-2, 8000)) ELSE NULL END),
CASE WHEN ca.PatPos = 1 THEN LEFT([Code],
ISNULL(NULLIF(ca.SpacePos,0)-0,1)) ELSE [Code] END) ca2(OrderBy2, OrderBy1)
WHERE [TypeID] = '1'
OUTPUT:
FFS1
FFS2
...
FFS12
FFS1.1
FFS1.2
...
FFS1.1E
FFS1.1R
...
FFS12.1
FFS12.2
FFS.12.1E
FFS12.1R
FFS12.2E
FFS12.2R
DESIRED OUTPUT:
FFS1
FFS1.1
FFS1.1E
FFS1.1R
....
FFS12
FFS12.1
FFS12.1E
FFS12.1R
What am I missing or overlooking?
EDIT:
Let me try to detail the table contents a little better. There are records for FFS1 - FFS12. Those are broken into X subs, i.e., FFS1.1 - FFS1.X to FFS12.1 - FFS12.X. The E and the R was not a typo, each sub record has two codes associated with it: FFS1.1E & FFS1.1R.
Additionally I tried using ORDER BY but it sorted as
FFS1
...
FFS10
FFS2
This will work for any count of parts separated by dots. The sorting is alphanumerical for each part separately.
DECLARE #YourValues TABLE(ID INT IDENTITY, SomeVal VARCHAR(100));
INSERT INTO #YourValues VALUES
('FFS1')
,('FFS2')
,('FFS12')
,('FFS1.1')
,('FFS1.2')
,('FFS1.1E')
,('FFS1.1R')
,('FFS12.1')
,('FFS12.2')
,('FFS.12.1E')
,('FFS12.1R')
,('FFS12.2E')
,('FFS12.2R');
--The query
WITH Splittable AS
(
SELECT ID
,SomeVal
,CAST(N'<x>' + REPLACE(SomeVal,'.','</x><x>') + N'</x>' AS XML) AS Casted
FROM #YourValues
)
,Parted AS
(
SELECT Splittable.*
,ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS PartNmbr
,A.part.value(N'text()[1]','nvarchar(max)') AS Part
FROM Splittable
CROSS APPLY Splittable.Casted.nodes(N'/x') AS A(part)
)
,AddSortCrit AS
(
SELECT ID
,SomeVal
,(SELECT LEFT(x.Part + REPLICATE(' ',10),10) AS [*]
FROM Parted AS x
WHERE x.ID=Parted.ID
ORDER BY PartNmbr
FOR XML PATH('')
) AS SortColumn
FROM Parted
GROUP BY ID,SomeVal
)
SELECT ID
,SomeVal
FROM AddSortCrit
ORDER BY SortColumn;
The result
ID SomeVal
10 FFS.12.1E
1 FFS1
4 FFS1.1
6 FFS1.1E
7 FFS1.1R
5 FFS1.2
3 FFS12
8 FFS12.1
11 FFS12.1R
9 FFS12.2
12 FFS12.2E
13 FFS12.2R
2 FFS2
Some explanation:
The first CTE will transform your codes to XML, which allows to address each part separately.
The second CTE returns each part toegther with a number.
The third CTE re-concatenates your code, but each part is padded to a length of 10 characters.
The final SELECT uses this new single-string-per-row in the ORDER BY.
Final hint:
This design is bad! You should not store these values in concatenated strings... Store them in separate columns and fiddle them together just for the output/presentation layer. Doing so avoids this rather ugly fiddle...

Ms Sql Trim comma , convert int , get data from another table

I have varchar Id like below,
'1','2','3' etc..
I split as comma after that i convert Id to int
SELECT FIRSAT_PERSONELLER_ID,
cast(LTRIM(C.value('n[1]','VARCHAR(50)')) as int )AS item1
FROM (SELECT *,
X = CAST('<myxml><nodes><n>' + REPLACE(FIRSAT_PERSONELLER_ID,',','</n></nodes><nodes> <n>') +
'</n></nodes></myxml>' AS XML)
FROM FIRSATLAR
)t
CROSS APPLY X.nodes('/myxml/nodes') Cols (C)
Result is like below:
item1:
1
2
3
i want to match above "item1" Id with my User Table.I tried below code however it did not work.I want to see User Names.
SELECT username
FROM UserTable
Where UserId=item1Id(İtem1Id does not appear)
Also i am not sure Id value is int or varchar.
Instead of above query , what i need to write ?
tSQL would look like this:
SELECT username
FROM UserTable a
join
(SELECT FIRSAT_PERSONELLER_ID,
cast(LTRIM(C.value('n[1]','VARCHAR(50)')) as int )AS item1
FROM (SELECT *,
X = CAST('<myxml><nodes><n>' + REPLACE(FIRSAT_PERSONELLER_ID,',','</n></nodes><nodes> <n>') +
'</n></nodes></myxml>' AS XML)
FROM FIRSATLAR
)t
CROSS APPLY X.nodes('/myxml/nodes') Cols (C)
) b on a.UserId = b.item1
hope this helps.