sql server column value to be converted in comma seperated - sql

Before this question is marked as duplicate, i know how it can be done but without doing a declare statement i want to do it within a query itself
like i have this query
select distinct costcenterid,costcentername,costcenterdesc,contactid,expirationdate,portal_id,
active,customername,branchid,id from costcenter cc
inner join branchesinportals bp on bp.portalid = cc.portal_id
the branchid and the id fields have different values but all other rows have same values so if i remove those and do a distinct it works good, i get one record
i want that it should always return me one record and combine the columns branchid and id as a comma separated values
i tried looking a this link which seems to be working but how can i integrate that link code with query
http://www.codeproject.com/Tips/635166/SQL-Column-Values-as-Comma-Separated-String

You can use FOR XML to solve this problem. Here is a list of column names (you can run it in any SQL Server Database):
Select Stuff((
Select ', ' + cast(COLUMN_NAME as varchar(max))
From INFORMATION_SCHEMA.COLUMNS
For XML PATH('')
), 1, 2, '');
Here is how to have a one-to-many value set show up:
Select Distinct C1.TABLE_NAME,
Stuff((
Select ', ' + Cast(COLUMN_NAME as VarChar (Max))
From INFORMATION_SCHEMA.COLUMNS C2
Where C1.TABLE_NAME = C2.TABLE_NAME
For Xml Path ('')
), 1, 2, '') Columns
From INFORMATION_SCHEMA.COLUMNS C1
Here is the output from my master database tables and columns:

Related

Return NON-Matched values from the result of XML path

I have a situation where I need to compare two tables where t1.ColumnA = t2.ColumnA and t1.ColumnB<>t2.ColumnB. The caveat to this problem is that t2.ColumnB is using a "FOR XML PATH" to concatenate like values from another table (linked server using OPENQUERY). This all has to be done within a View.
To concatenate the rows, I am using the following code:
SELECT DISTINCT
CAST(A.CHECK_NUMBER AS nvarchar) [CHECK_NUMBER]
,(
SELECT B.INVOICE_NUMBER + '|'
FROM OPENQUERY([SERVER], 'SELECT * FROM CHECK_LISTING ') B
WHERE B.CHECK_NUMBER = A.CHECK_NUMBER
AND (NULLIF (B.INVOICE_NUMBER, '') IS NOT NULL)
FOR XML PATH('')
) [INVOICE_NUMBER]
, (
SELECT LTRIM(RTRIM(B.PURCHASE_ORDER_ID)) + '|'
FROM OPENQUERY([SERVER], 'SELECT * FROM CHECK_LISTING ') B
WHERE B.CHECK_NUMBER = A.CHECK_NUMBER
AND (NULLIF (B.PURCHASE_ORDER_ID, '') IS NOT NULL)
FOR XML PATH('')
) [PURCHASE_ORDER_ID]
FROM OPENQUERY([SERVER], 'SELECT * FROM CHECK_LISTING ') AS A
This works perfectly and concatenates just like it needs to. My problem is that my next view I created was to run that view against a local table to see the difference in the INVOICE_NUMBER.
SELECT
A.EntryID,
A.Check#,
A.CheckDate,
A.CheckAmount,
A.VendorID,
A.VendorName,
B.INVOICE_NUMBER,
A.Invoice#
FROM dbo.APChecks AS A
LEFT JOIN
dbo.CHECKS_Step2 AS B
ON A.Check#=B.CHECK_NUMBER
WHERE (A.Invoice# != B.INVOICE_NUMBER)
When I try to run this, the query takes at least 25+ minutes. I had to stop the query manually. Some concatenated values are longer than 1000 chars. I was told that it was not possible to INDEX on a dynamic entry like an XML PATH.
Any suggestions? Thank you in advance.

SQL Server: Convert single row to comma delimited (separated) format

As the title states, I need help in converting a single row of data E.g,
col1 col2 col3 <-- This are column names
value1 value2 value3
To something like
dataResult <-- this is the column name from running the procedure or call
value1,value2,value3
The requirements are that this call ( or rather procedure) needs to be able to accept the results of sql queries of any column length and is able to convert that row to a comma delimited string format. Been stuck at this for weeks any help would be greatly appreciated...
EDIT*
Assume the unique key is the first column. Also assume that only 1 row will be returned with each query. Multiple rows will never occur.
The idea is to convert that row to a comma separated string without having to select the column names manually (in a sense automatically convert the query results)
You might try it like this:
A declared table variable to mock-up as test table. Be aware of the NULL value in col2!
DECLARE #tbl TABLE(col1 VARCHAR(100),col2 VARCHAR(100),col3 VARCHAR(100));
INSERT INTO #tbl VALUES('test1',NULL,'test3');
--This is the query:
SELECT
STUFF(
(
SELECT ',' + elmt.value('.','nvarchar(max)')
FROM
(
SELECT
(
/*YOUR QUERY HERE*/
SELECT TOP 1 *
FROM #tbl
/*--------------------*/
FOR XML AUTO ,ELEMENTS XSINIL,TYPE
)
) AS A(t)
CROSS APPLY t.nodes('/*/*') AS B(elmt)
FOR XML PATH('')
),1,1,'')
FOR XML AUTO will return each row as XML with all the values within attributes. But this would omit NULL values. Your returned string would not inlcude the full count of values in this case. Stating ELEMENT XSINIL forces the engine to include NULL values into the XML. This CROSS APPLY t.nodes('/*/*') will return all the elements as derived table and the rest is re-conactenation.
See the double comma in the middle! This is the NULL value of col2
test1,,test3
ATTENTION: You must be aware, that the whole approach will break, if there is a comma part of a (string) column...
Hint
Better was a solution with XML or JSON. Comma separated values are outdated...
Applay the next Approach:-
Use For Xml to sperate comma,
Get Columns Names Via using INFORMATION_SCHEMA.COLUMNS.
According to your need, select TOP (1) for getting First
Row.
Demo:-
Create database MyTestDB
go
Use MyTestDB
go
Create table Table1 ( col1 varchar(10), col2 varchar(10),col3 varchar(10))
go
insert into Table1 values ('Value1','Value2','Value3')
insert into Table1 values ('Value11','Value12','Value13')
insert into Table1 values ('Value21','Value22','Value23')
go
Declare #Values nVarchar(400),
#TableName nvarchar (100),
#Query nvarchar(max)
Set #TableName = 'Table1'
Select #Values = Stuff(
(
Select '+'','' + ' + C.COLUMN_NAME
From INFORMATION_SCHEMA.COLUMNS As C
Where C.TABLE_SCHEMA = T.TABLE_SCHEMA
And C.TABLE_NAME = T.TABLE_NAME
Order By C.ORDINAL_POSITION
For Xml Path('')
), 1, 2, '')
From INFORMATION_SCHEMA.TABLES As T
where TABLE_NAME = #TableName
select #Values = right(#Values,len(#Values)-4)
select #Query = 'select top(1)' + #Values + ' from ' + #TableName
exec sp_executeSQL #Query
Result:-

How to find table names which have a same value in other tables based aone column

I have a database with many tables and that table has a common column. How can I retrieve that table which have same value in that column?
ex:-
I have 25 table, all tables have a column name CCODE now I want to know which tables have same value for this column?
The following statement will create an UNION SELECT what brings back all the data you need in one result set. Best is to set the query output to text and don't forget to set the query option max text to highest (8192). Take the result of this SELECT into a new SQL window and execute it:
WITH AllTablesWithMyColumn AS
(
SELECT DISTINCT TABLE_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME='CCODE'
)
SELECT STUFF(
(
SELECT 'UNION SELECT ''' + TABLE_NAME + ''' AS TableName, CCODE FROM ' + TABLE_NAME + CHAR(13) + CHAR(10)
FROM AllTablesWithMyColumn
FOR XML PATH(''),TYPE
).value('.','varchar(max)'),1,6,'')
If you need any further help, just tell me...

SQL for concatenating strings/rows into one string/row? (How to use FOR XML PATH with INSERT?)

I am concatenating several rows/strings in an table (on Microsoft SQL Server 2010) into a string by using a method as suggested here:
SELECT ',' + col FROM t1 FOR XML PATH('')
However, if I try to insert the resulting string as (single) row into another table like so:
INSERT INTO t2
SELECT ', ' + col FROM t1 FOR XML PATH('')
I receive this error message:
The FOR XML clause is not allowed in a INSERT statement.
t2 currently has a single column of type NVARCHAR(80). How can I overcome this problem, i.e. how can I collapse a table t1 with many rows into a table t2 with row that concatenates all the strings from t1 (with commas)?
Rather than xml path why not do it like this?
DECLARE #Cols VARCHAR(8000)
SELECT #Cols = COALESCE(#Cols + ', ', '') +
ISNULL(col, 'N/A')
FROM t1
Insert into t2 values(#Cols);
You need to cast it back to an nvarchar() before inserting. I use this method, deletes the first separator as well and as I'm doing the , type part, it handles entities correctly.
insert into t2
select stuff((
select ', ' + col from t1
for xml path(''), type
).value('.', 'nvarchar(80)'), 1, 2, '')
So you concatenate all col with prepending comma+space as an xml-object. Then you take the .value() of child with xquery-path . which means "take the child we are at, don't traverse anywhere". You cast it as an nvarchar(80) and replace a substring starting at position 1 and length 2 with an empty string ''. So the 2 should be replaced with however long your separator is.

SQL Server: how to remove last comma after combining rows using XML Path

I found a way to combine multiple row's into one row which is comma separated but now I would like to remove the last comma.
CREATE TABLE supportContacts
(
id int identity primary key,
type varchar(20),
details varchar(30)
);
INSERT INTO supportContacts (type, details)
VALUES ('Email', 'admin#sqlfiddle.com'),
('Twitter', '#sqlfiddle');
This query combines types, but I want to now remove the last comma:
SELECT top (2)
type + ', ' AS 'data()'
FROM
supportContacts
ORDER BY
type DESC
FOR XML PATH('')
This is the current result:
Twitter, Email,
While you already have an answer, another common idiom that you'll see is:
select stuff((
SELECT top (2)
', ' type AS 'data()'
FROM
supportContacts
ORDER BY
type DESC
FOR XML PATH('')
), 1, 2, '')
This says "take the result of the select and replace the two characters starting at position 1 with a zero-length string".
This works for me->
1.Inserting comma Before Data
2.Using Stuff to Remove it
select (stuff((
SELECT ', '+ Name AS 'data()'
FROM Table_1
FOR XML PATH('')),
Count('ID')
, 1, ' '))as Result
declare #BigStrRes8K nvarchar(4000)
SELECT #BigStrRes8K = ( SELECT top (2) [type] + ', ' AS 'data()'
FROM supportContacts
ORDER BY type DESC
FOR XML PATH('') )
SELECT LEFT(RTRIM(#BigStrRes8K), ( LEN(RTRIM(#BigStrRes8K))) - 1) as FinalNoComma
I would never do this where I controlled the render code. I would teach the caller to handle the trailing comma. Also you have to allow for nulls and the 4K or 8K limit of SQL rows