SQL comma separated values - sql

I am using this query in another big query.
I need this query to return comman separated values (so John,David,Brian,Jake) and without using any intermediate variable.
I'm using SQL Server 2014.
Could you please provide necessary SQL?
SELECT
--#listStr = (COALESCE(#listStr + ',', '') + ShortName)
X.ShortName
FROM
(
SELECT 'John' AS ShortName UNION ALL
SELECT 'David' AS ShortName UNION ALL
SELECT 'Brian' AS ShortName UNION ALL
SELECT 'Jake' AS ShortName
) X

you can use STUFF function, FOR XML PATH can be used to concatenate the values with comma as separator and STUFF removes the leading comma.
SELECT STUFF((SELECT ',' + ShortName
FROM
(
SELECT 'John' AS ShortName UNION ALL
SELECT 'David' AS ShortName UNION ALL
SELECT 'Brian' AS ShortName UNION ALL
SELECT 'Jake' AS ShortName
) X
FOR XML PATH('')),1,1,'' )

Related

How can I do a replace with values from a table

This is my current code, what I want to do is rather than hard code this replace is put those values in a table and use those values to do the replace without a while or cursor. Keep in mind multiple replaces may happen to the same field for instance Mr. Guy would replace the "." but then would also need to replace "Mr ".
SELECT
REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(TRIM(di.FirstName), '.', ''), ',', ''), 'Mr ', ''), 'Dr ', ''), 'Mrs ', ''), 'Ms', '')
FROM core..asdf di
If your DBMS supports both GROUP_CONCAT() (or equivalent, like LISTAGG() in Vertica),
You can
create an in-line table with the titles you want to remove,
group-concatenate that in-line table into a single string, bar separated
surround that bar-separated list by rounded parentheses, and add '\b' for "word" boundary, '\.?' meaning zero or one times the dot character (and not any character), and '\s*' for one or more white spaces
and finally use that regular expression you just created on a REGEXP_REPLACE() call.
WITH
indata(fname) AS (
SELECT 'Mr Arthur'
UNION ALL SELECT 'Mrs Tricia'
UNION ALL SELECT 'Ms Eccentrica'
UNION ALL SELECT 'Dr Gag'
UNION ALL SELECT 'Mr. Arthur'
UNION ALL SELECT 'Mrs. Tricia'
UNION ALL SELECT 'Ms. Eccentrica'
UNION ALL SELECT 'Dr. Gag'
)
,
titles(title) AS (
SELECT 'Mr'
UNION ALL SELECT 'Mrs'
UNION ALL SELECT 'Ms'
UNION ALL SELECT 'Dr'
)
,
regx(regx) AS (
SELECT
'('||LISTAGG(title USING PARAMETERS separator='|')||')\b\.?\s*'
-- OR GROUP_CONCAT(title,',') in other DBMSs ...
FROM titles
)
-- control query ...
-- SELECT * FROM regx;
-- out regx
-- out ----------------------
-- out (Mr|Mrs|Ms|Dr)\.?\s*
SELECT
REGEXP_REPLACE(fname,regx) AS fname
FROM indata CROSS JOIN regx;
-- out fname
-- out ------------
-- out Arthur
-- out Tricia
-- out Eccentrica
-- out Gag
-- out Arthur
-- out Tricia
-- out Eccentrica
-- out Gag

substract specific string from data sql

I am new to SQL
If I have a column like this
ID
00001234
00012345
00001235
00123456
I want to see a column of ID without '0' Like this
ID
1234
12345
1235
123456
How can I start? any advice?
In SQL Server you can use:
SELECT ID,
REPLACE(LTRIM(REPLACE(ID, '0', ' ') ), ' ', '0')
FROM mytable
The above can be easily adjusted to any other RDBMS you may use.
Cast it to Bigint and cast it back to varchar
Note:Assumption: RDBMS SQL SERVER, ID is of character type
SELECT * INTO #TAB FROM (
select '00001234' ID
UNION ALL
select '00012345'
UNION ALL
select '00001235'
UNION ALL
select '00123456'
)A
SELECT CAST(CAST(ID AS BIGINT) AS VARCHAR(50)) FROM #TAB

How to group through a string part?

I've a table which contains logs from a web portal, it contains the url visited, the request duration, the referer...
One of these columns is the path info and contains strings like following:
/admin/
/export/
/project2/
/project1/news
/project1/users
/user/id/1
/user/id/1/history
/user/id/2
/forum/topic/14/post/456
I would like to calculate with sql queries some stats based on this column, so I would like to know how can I create aggregate based on the first part of the path info?
It'd let me count number of url starting by /admin/, /export/, /project1/, /project2/, /user/, /forum/, ...
Making it with a programming language would be easy with regex, but I read that similar function does not exists on SQLServer.
I would use CHARINDEX() to find the first occurrence of the "/" starting AFTER the leading first character '/', so anything AFTER the second is stripped off.
select
LEFT( pathInfo, CHARINDEX( '/', pathInfo, 2 )) as RootLevelPath,
count(*) as Hits
from
temp
group by
LEFT( pathInfo, CHARINDEX( '/', pathInfo, 2 ))
Working result from SQLFiddle
DRapp's is perfect for grouping on the first fragment of the URL. If you need to group by other levels it might get unwieldy to manage the nested LEFT/CHARINDEX statements.
Here's one way to group by a parameterized level:
declare #t table (pathId int identity(1,1) primary key, somePath varchar(100));
insert into #t
select '/admin/' union all
select '/export/' union all
select '/project2/' union all
select '/project1/news' union all
select '/project1/users' union all
select '/user/id/1' union all
select '/user/id/1/history' union all
select '/user/id/2' union all
select '/forum/topic/14/post/456' union all
select '/forum/topic/14/post/789' union all
select '/forum/topic/14/post/789'
declare #level int =1;
;with fragments as
( select pathId,
[n] = x.query('.'),
[Fragment] = x.value('.', 'varchar(100)')
from ( select PathId,
cast('<r>' + replace(stuff(somePath, 1, 1, ''), '/', '</r><r>') + '</r>' as xml)
.query('r[position()<=sql:variable("#level")]')
from #t
) d (PathId, X)
)
select count(*), [path] = max(r.v)
from fragments f
cross
apply ( select '/' + p.n.value('.', 'varchar(100)')
from fragments
cross
apply n.nodes('r')p(n)
where PathId = f.PathId
for xml path('')
) r(v)
group
by fragment;

How to format TSQL SELECT output in SQL Sever

How to loop through a select statement results to have a formatted text?
for example the select is like:
select name from table
and we want a variable #names like this:
"name1,name2,name3"
Database is SQL Server 2005
If table contains several records, i.e.:
1, name1, ..
2, name2, ..
3, name3, ..
then this query:
DECLARE #names VARCHAR(MAX)
SELECT #names = COALESCE(#names + ', ', '') + name
FROM table
will produce next result:
name1, name2, name3
See COALESCE on MSDN
This would need to be done within a function. There's no quick way to do this. Normally you would do this within your client side code.
If you plan on making a function that you do on each row form another query it will be really slow, because the function needs to be called for each row. You should work with sets of data at one time, it does all rows at one time. This is an example of how to concatenate multiple values for each row of another query:
set nocount on;
declare #t table (id int, name varchar(20), x char(1))
insert into #t (id, name, x)
select 1,'test1', 'a' union
select 1,'test1', 'b' union
select 1,'test1', 'c' union
select 2,'test2', 'a' union
select 2,'test2', 'c' union
select 3,'test3', 'b' union
select 3,'test3', 'c'
SELECT p1.id, p1.name,
stuff(
(SELECT
', ' + x
FROM #t p2
WHERE p2.id=p1.id
ORDER BY name, x
FOR XML PATH('')
)
,1,2, ''
) AS p3
FROM #t p1
GROUP BY
id, name
OUTPUT:
id name p3
----------- -------------------- -----------
1 test1 a, b, c
2 test2 a, c
3 test3 b, c

Concat field value to string in SQL Server

I need a similar function to Oracle WM_CONCAT in SQL Server, which returns a comma separated list of whatever field you pass it as argument. For example, in Oracle,
select WM_CONCAT(first_name) from employee where state='CA'
returns "John, Jim, Bob".
How can I do this in SQL Server?
Thanks
In SQL Server 2017 STRING_AGG function has been added
SELECT t.name as TableName
,STRING_AGG(c.name, ';') AS FieldList
FROM sys.tables t
JOIN sys.columns c
ON t.object_id = c.object_id
GROUP BY t.name;
The actual answer:
SELECT
SUBSTRING(buzz, 2, 2000000000)
FROM
(
SELECT
firstname
FROM
employee
WHERE
State = 'CA'
FOR XML PATH (',')
) fizz(buzz)
A common question here. Some searches:
FOR XML PATH
concat rows csv [sql-server]
Try this:
drop table #mike_temp
go
select * into #mike_temp
from (select 'Ken' as firstname, 'CO' as state
union all
select 'Mike' as firstname, 'CO' as state
union all
select 'Tom' as firstname , 'WY' as state
) a
go
SELECT distinct
state
,STUFF((SELECT ', ' + b.firstname FROM #mike_temp b where a.state = b.state FOR XML PATH('')),1, 2, '') AS CSVColumn
from #mike_temp a
AFAIK, you need to do it by yourself.
You could build an user defined function that loop with a cursor the records of Employee where the state is CA and returns the concatenation of their names.
SELECT Field1, Substring(Field2, 2, LEN(Field2)) AS Field2 FROM
(
SELECT
[InnerData].Field1,
(SELECT ',' + Field2 FROM #Fields WHERE Field1=[InnerData].Field1 FOR XML PATH('')) AS Field2
FROM
(
SELECT DISTINCT Field1 FROM #Fields
) AS [InnerData]
) AS OuterData
I got this Query from this Link
Refer this Link for more Clarification
try this
select
wm_concat(name)
from
employee
where
state='CA'
group by
state