SQL Server : combine multiple records into one field - sql-server-2014

I have created the following SQL script:
SELECT
E.ID,
abc = STUFF((SELECT ' ' + E2.ExclusionID
FROM Exclusion E2
WHERE E.ID = E2.ID
FOR XML PATH ('')), 1, 0, '')
FROM
Exclusion E
GROUP BY
E.ContractMovementID
It combines all exclusion records for the ID into one record and displays as below:
ID ExclusionID
-------------------
1 123
2 2345
3 4567
However, I would like it to display as:
ID ExclusionID
-------------------
1 1 2 3
2 23 45
3 45 67
So that the columns are separated with space, however, I cannot seem to get it to put a space between them. Can anyone help me with this? (I hope this makes sense)
Thanks
Jessica

How about this:
SELECT
E.ID,
abc = STUFF((SELECT ' ' + E2.ExclusionID
FROM Exclusion E2
WHERE E.ID = E2.ID
FOR XML PATH ('')), 1, 1, '')
FROM
Exclusion E
GROUP BY
E.ContractMovementID

I have found a solution, because the exclusion.id was an INT data type i had to convert it into a varchar to be able to add a seperator.
SELECT
E.ID,
abc = STUFF((SELECT CAST(E2.ExclusionID AS VARCHAR) + ','
FROM Exclusion E2
WHERE E.ID = E2.ID
FOR XML PATH ('')), 1, 0, '') FROM
Exclusion E GROUP BY
E.ContractMovementID

Related

multiple values in 1 column when you join 2 tables

table 1 - employee
id empname
--------------
1 andy
2 brady
table 2 - employee phone numbers
id number empid
----------------
1 1111 1
2 2222 2
3 3333 1
4 4444 1
Need a sql query to display the following
id empname numbers
------------------
1 andy 1111,3333,4444
2 brady 2222
If you are using MySQL, you can use GROUP_CONCAT funcion, that basically concatenate every value composing the group. You could try this:
SELECT EMP.ID,
EMP.EMPNAME,
GROUP_CONCAT(EPH.NUMBER) AS NUMBERS
FROM EMPLOYEE EMP
JOIN EMPLOYEE_PHONE EPH
ON EMP.ID = EPH.EMPID
GROUP BY EMP.ID
Also, if you want to separate your values with something different of a "," you can add the syntax SEPARATOR " " after the column inside group concat, if you want to separate with spaces in this particular example
if you use SQL SERVER I think this will do it for you, if not maybe a close guess without data. But! I used STUFF and selected the Number and split them by , and ordered it
SELECT
t1.ID,t2v1.empname,
STUFF((SELECT ',' + t2v2.number
FROM Table2 t2v2
WHERE t2v2.ID = t2v1.ID
ORDER BY number
FOR XML PATH('')), 1, 1, '') [numbers]
FROM Table1 t1
inner join table2 t2v1 on t1.id = t2v1.id
GROUP BY t1.ID, t1.Name
ORDER BY 1
Try this:
SELECT e.id, e.name, CONCATENATE(ep.number, ',') as phonelist
FROM Employees e INNER JOIN EmployeePhone ep ON e.id = ep.empid
Reference Doc: http://www.peteonsoftware.com/index.php/2009/12/11/creating-a-comma-separated-list-from-a-sql-grouping/

SQL: How can I get the items value in one row using sql query?

How can I get the items value in one row using sql query like 20,10,15,40,15?
Table Name : ites
id | items
===============
1 | 20
2 | 10
3 | 15
4 | 40
5 | 15
As example we can get sum like this
Query
SELECT SUM(items) FROM `ites`
Result
SUM(items)
100
In same manner I want to get the value like 20,10,15,40,15 using a query?
You can use GROUP_CONCAT:
select GROUP_CONCAT(items) FROM ites
Ignoring the IDs of item
select GROUP_CONCAT(items)as myvalues FROM ites
With multiple occurrence of items
SELECT ID
,STUFF((SELECT ', ' + CAST(items AS VARCHAR(10)) [text()]
FROM iten
WHERE ID = t.ID
FOR XML PATH(''), TYPE)
.value('.','NVARCHAR(MAX)'),1,2,' ') myvalues
FROM iten t
GROUP BY ID

Retrieve Distinct concat values from MySQL table

I have an SQL table advert
id name cat
11 abc ab
12 acb ab, bc
13 abb bcd
14 abcd ad
15 acbd de
16 abbd ad
On using DISTINCT function I am getting an output like this
Query:
SELECT DISTINCT cat FROM advert;
Output:
ab
ab, bc
bcd
ad
de
WHAT changes do I need to make in my query for output like this
ab
bc
bcd
ad
de
select distinct trim(substring_index(substring_index(cat,',',n),',',-1)) as cat
from t join (select 1 as n union all select 2 union all select 3) r
on cat like concat('%',repeat(',%',n-1))
I think you should change your table structure and make it like this.
tblName
id | name
11 abc
12 acb
13 abb
14 abcd
15 acbd
16 abbd
tblCat
id | name_id | cat
some ids* 11 ab
12 ab
12 bc
13 bcd
14 ad
15 de
16 ad
In this way you can easily query and manage your data in your tables.
You should fix your data structure so you are not storing comma-delimited lists in columns. That is the wrong way to store data in a relational database . . . as you can see by the problems for answering this simple question. What you want is a junction table.
Sometimes, we are stuck with other peoples bad designs. You say that there are only two or values, then you can do:
select cat
from ((select substring_index(cat, ', ', 1) as cat
from advert
) union all
(select substring_index(substring_index(cat, ', ', 2), ', ', -1) as cat
from advert
where cat like '%, %'
) union all
(select substring_index(substring_index(cat, ', ', 3), ', ', -1) as cat
from advert
where cat like '%, %, %'
)
) c
group by cat;
First... I would create a statement that would turn all the rows into one big massive comma delimited list.
DECLARE #tmp VarChar(max)
SET #tmp = ''
SELECT #tmp = #tmp + ColumnA + ',' FROM TableA
Then use the table valued udf split described by this SO article to turn that massive string back into a table with a distinct clause to ensure that it's unique.
https://stackoverflow.com/a/2837662/261997
SELECT DISTINCT * FROM dbo.Split(',', #tmp)
Full code example:
if object_id('dbo.Split') is not null
drop function dbo.Split
go
CREATE FUNCTION dbo.Split (#sep char(1), #s varchar(512))
RETURNS table
AS
RETURN (
WITH Pieces(pn, start, stop) AS (
SELECT 1, 1, CHARINDEX(#sep, #s)
UNION ALL
SELECT pn + 1, stop + 1, CHARINDEX(#sep, #s, stop + 1)
FROM Pieces
WHERE stop > 0
)
SELECT pn,
SUBSTRING(#s, start, CASE WHEN stop > 0 THEN stop-start ELSE 512 END) AS s
FROM Pieces
)
go
declare #t table (colA varchar(max))
insert #t select '111, 223'
union all select '333'
union all select '444'
union all select '777,999';
select ltrim(rtrim(s.s)) as colC
from #t t
cross apply
dbo.split(',', t.colA) s

Check if an employee email contains his name - not a case sensitive

I would like to display the name and the email associated with it when the employee name is contained within the email. A user can have more than one email.
employee
id name
1 Steve Been
2 Rob Kem
3 Bob Kimi
Emails
emplyee_id email
1 steve#domain.com
1 007#domain.com
1 Been#domain.com
2 Robkem#domain.com
2 Rob.Kem#domain.com
3 Boooob#domain.com
3 kimi#domain.com
The query should not be case sensitive. I would like this query to show me something like:
name email
Steve Been steve#domain.com
Steve Been Been#domain.com
Rob Kem Robkem#domain.com
Rob Kem Rob.Kem#domain.com
Bob Kimi kimi#domain.com
I tried this but I got empty output:
select empl.Name as 'employee Name', em.email as 'Product Name'
from email em JOIN employee empl
ON em.employee_id = empl.ID
WHERE FIND_IN_SET(LOWER(empl.Name),LOWER(em.Name))
Try
SELECT e.name,
m.email
FROM emails m JOIN
employee e ON m.emplyee_id = e.id
WHERE INSTR(m.email, SUBSTRING_INDEX(e.name, ' ', 1)) > 0
OR INSTR(m.email, SUBSTRING_INDEX(e.name, ' ', -1)) > 0
SQLFiddle
INSTR() is case insensitive unless one of the stings is a binary string, but you can always add LOWER() for a good measure.
UPDATE: As per your additional request you can do that with a query like this
SELECT name,
total,
matched,
total - matched unmatched
FROM (
SELECT e.name,
COUNT(*) total,
SUM(CASE WHEN INSTR(m.email, SUBSTRING_INDEX(e.name, ' ', 1)) > 0
OR INSTR(m.email, SUBSTRING_INDEX(e.name, ' ', -1)) THEN 1 ELSE 0 END) matched
FROM emails m JOIN
employee e ON m.emplyee_id = e.id
GROUP BY e.id, e.name) q
SQLFiddle

Combine multiple rows into single row in an CSV file in SSIS

I load data from SQL to CSV file. And my csv records are in the following way.
Eid ename desig sourceD location
1 Ralf PM 1 UK
1 Ralf PM 1 USA
2 Marty PL 3 GBR
3 Levis BA 5 UK
4 Ricky BI 7 RSA
4 Ricky BI 7 FRA
now i want to combine EID 1 and 4 into single rows. My output has to be in the following way
Eid ename desig sourceD location
1 Ralf PM 1 UK, USA
2 Marty PL 3 GBR
3 Levis BA 5 UK
4 Ricky BI 7 RSA, FRA
I have only CSV File i dont have any sql Query or anything.
SQL Fiddle
SQL Query
select c1.Eid, c1.ename,c1.desig,c1.sourceD,
( SELECT x.location + ', '
FROM Contacts x
WHERE c1.Eid = x.Eid
ORDER BY x.location
FOR XML PATH ('')
) as Locations
from Contacts c1
group by c1.Eid, c1.ename,c1.desig,c1.sourceD
Working ?
If you want without comma in the end:
SELECT c1.Eid, c1.ename,c1.desig,c1.sourceD,
LEFT( ( SELECT x.location + ', '
FROM Contacts x
WHERE c1.Eid = x.Eid
ORDER BY x.location
FOR XML PATH ('')
),LEN(( SELECT x.location + ', '
FROM Contacts x
WHERE c1.Eid = x.Eid
ORDER BY x.location
FOR XML PATH ('')
))-1) AS Locations
FROM Contacts c1
GROUP BY c1.Eid, c1.ename,c1.desig,c1.sourceD
This Query will let you avoid lenght 0:
SELECT c1.Eid, c1.ename,c1.desig,c1.sourceD,
LEFT( ( SELECT x.location + ', '
FROM Contacts x
WHERE c1.Eid = x.Eid
ORDER BY x.location
FOR XML PATH ('')
),CASE WHEN LEN(( SELECT x.location + ', '
FROM Contacts x
WHERE c1.Eid = x.Eid
ORDER BY x.location
FOR XML PATH ('')
))=0 THEN 1 ELSE LEN(( SELECT x.location + ', '
FROM Contacts x
WHERE c1.Eid = x.Eid
ORDER BY x.location
FOR XML PATH ('')
)) END -1) AS Locations
FROM Contacts c1
GROUP BY c1.Eid, c1.ename,c1.desig,c1.sourceD