Combine Multiple Rows into one row on a single table - sql-server

I have a table that contains multiple Insurance policies for each client that contains
Order (Primary, Secondary etc. up to 9 possible Insurance policies)
I need one row per client containing all the client's insurance policies in order of importance.
for example:
Client, Order, Company, Number, Start, End, Co-Pay, Active?
1 1 BCBS 12345 1/1/2019 $10 Active
1 2 Medicare X21Y52 2/1/2018 Active
1 6 Self-Pay
2 6 Medicare X21Y52 2/1/2018 Active
2 8 Self-Pay
I need a single row for each Client with the data for each Active Policy
1,1,BCBS,12345,1/1/2019,,$10,Active,2,Medicare,X21Y52,2/1/2018,,,Active,6,Self-Pay,,,,,
2,6,Medicare,x22y22,7/1/2002,,,Active,8,Self-Pay,,,,,,
How can I code to get the desired result.
There is a maximum of 9 policy references
Only want Active policies

As you didn't post your schema, i just make some assumption on the data type. Note that you need to convert to string before concatenation
select t.Client, stuff(csv, 1, 1, '')
from (
select distinct Client
from a_table t
) t
cross apply
(
select ',' + coalesce(x.Company, '') +
',' + coalesce(x.Number, '') +
',' + coalesce(convert(varchar(10), [Start], 121), '') +
',' + . . .
from a_table x
where x.Client = t.Client
and x.Active = 'Active'
order by [Order]
for xml path ('')
) c (csv)

Related

How to Add values of column 2 at the end of column 1 if value of column 1 been duplicate

I have a table as shown below
[ID] [ Company ] [ShippingCity] [externalID]
1 Microsoft Bellevue MM2547
2 Microsoft Bellevue MM2548
3 Microsoft Seattle MM2549
4 Microsoft Null MM2550
I want to be able to have the name in one select statement and apply a logic that gives me name of company base on it.
I am using this logic :
SELECT CASE WHEN SHIPPINGCITY IS NULL THEN CONCAT(COMPANY,'-',EXTERNALID)
ELSE CONCAT(COMPANY,'-',SHIPPINGCITY) ELSE **THIS PART IS WHERE i AM LOST**
IF SHIPPING CITY IS SAME ADD THE EXTERNAL ID INTO SECOND RECORD
I am aware that I can use only external ID but problem is client I am working with wants the first record without externalID at the end so they are looking for a result as shown below:
[ID] [ Company ] [ShippingCity] [externalID]
1 Microsoft-Bellevue Bellevue MM2547
2 Microsoft-Bellevue-MM2548 Bellevue MM2548
3 Microsoft-Seattle Seattle MM2549
4 Microsoft-MM2550 Null MM2550
is there any logic that I can use to get it in one single SELECT statement?
Thanks a lot in advance
This should do the trick:-
select
id,
case
when ShippingCity is null then Company + '-' + ExternalID
when row_number() over(partition by Company, ShippingCity order by ExternalID) = 1 then Company + '-' + ShippingCity
else Company + '-' + ShippingCity + '-' + ExternalID
end as [Company],
ShippingCity,
ExternalID
from [Your Table]
order by id
You could use the following logic, which makes use of the row_number to partition it based on company and shippingcity. Hope it makes sense to you.
DECLARE #t TABLE (ID INT, Company VARCHAR(255), ShippingCity VARCHAR(255), ExternalId VARCHAR(255))
INSERT INTO #t VALUES
(1,'Microsoft','Bellevue','MM2547'),
(2,'Microsoft','Bellevue','MM2548'),
(3,'Microsoft','Seattle','MM2549'),
(4,'Microsoft',Null,'MM2550')
SELECT sub.ID,
CASE WHEN sub.ShippingCity IS NULL THEN sub.Company + '-' + sub.ExternalId
WHEN sub.r = 1 THEN sub.Company + '-' + sub.ShippingCity
WHEN sub.r > 1 THEN sub.Company + '-' + sub.ShippingCity + '-' + sub.ExternalId END AS Company
, sub.ShippingCity, sub.ExternalId
FROM
(
SELECT Id, Company, ShippingCity, ExternalId,
ROW_NUMBER() OVER(PARTITION BY Company, ShippingCity ORDER BY Company, ShippingCity, ExternalId) AS r
FROM #t
) AS sub
ORDER BY ID
Result
ID Company ShippingCity ExternalId
----------------------------------------------------------
1 Microsoft-Bellevue Bellevue MM2547
2 Microsoft-Bellevue-MM2548 Bellevue MM2548
3 Microsoft-Seattle Seattle MM2549
4 Microsoft-MM2550 NULL MM2550

TSQL Search Box First Name Surname order priority

I have a front end search box where the user can search for someone by firstname, middlename, surname or job title and bulk of the backend code looks like this:
SELECT TOP 50 * FROM (SELECT [EmployeeId], SUM(MatchOrder) as MatchOrder
FROM (SELECT
[EmployeeId],
CASE WHEN A.[EmployeeFieldId] = 4 Then 15 --Surname
WHEN A.[EmployeeFieldId] in (1, 2) Then 15 --PreferredName, FirstName
WHEN A.[EmployeeFieldId] = 3 Then 5 --MiddleName
WHEN A.[EmployeeFieldId] = 5 Then 20 --JobTitle
ELSE 3
END as MatchOrder
FROM [latest].[EmployeeAttributes] A
WHERE (' + #search + ')
) internal
GROUP BY EmployeeId) A
join dbo.vwEmployees E on E.EmployeeId = A.EmployeeId -- TEMP
ORDER BY 2 DESC'
Each employeeID is given a score (MatchOrder) which is totalled depending on how many of the above criteria are met (e.g. First Name + Surname match = 30) and then the search is ordered by the MatchOrder score to be displayed by the front end, But the problem is that if someone's First and Surname are very similar, e.g. Patrick Patterson and I only search for Pat Rice, then Patrick Patterson (30 pts) appears above Patrick Rice(30pts) because the First Name is being matched twice.
I'd like for it to either lower the points score if the match is doubly made, or modify my switch statement to somehow do this (nested case?
Do you know how I can combat this? Any help would be appreciated.
Thanks
Since [EmployeeFieldId] is always mapped to the same [MatchOrder], you should be able to control this by including [EmployeeFieldId] in the "internal" result set and slapping a DISTINCT clause on the SELECT:
SELECT DISTINCT
[EmployeeId],
[EmployeeFieldId],
CASE WHEN A.[EmployeeFieldId] = 4 Then 15 --Surname
WHEN A.[EmployeeFieldId] in (1, 2) Then 15 --PreferredName, FirstName
WHEN A.[EmployeeFieldId] = 3 Then 5 --MiddleName
WHEN A.[EmployeeFieldId] = 5 Then 20 --JobTitle
ELSE 3
END as MatchOrder
FROM [latest].[EmployeeAttributes] A
WHERE (' + #search + ')
That way, each employee will get at max one of the same field IDs applied towards their score.

Correlation items like amazon.com

we are in retail company and they need correlation items that have related together
in sales may sales id have full combination or have more than them
1. a b 1200
2. a c 1700
3. a b c 1200
i was tring
select [itemids],count(*)from (
SELECT
S.Salesid ,
STUFF((SELECT ', ' + S1.itemid
FROM banta_sales_ts S1
WHERE S.Salesid = S1.Salesid
FOR XML PATH('')), 1, 1, '') [itemids]
FROM banta_sales_ts S
GROUP BY S.Salesid) as grp group by [itemids]
but that related salesid i need full correlation items

Sql Multiple row merge into single row with specific pattern

Sql select query which gives merge multiple row into one single row
using sqlserver 2005 and above
I have two tables ie (tb_master,tb_tasks)
create table tb_tasks(
id int IDENTITY(1,1) NOT NULL,
id_tbmaster int NOT NULL,
Tasks nvarchar(max) NOT NULL
)
create table tb_master(
id int IDENTITY(1,1) NOT NULL,
grade nchar(10) NOT NULL,
name nvarchar(50) NOT NULL,
task_date datetime NOT NULL,
)
select * from tb_master
id grade name task_date
1 A John 2012-02-13 10:40:00.000
2 B Tom 2012-02-13 10:40:00.000
select tb_tasks
id id_tbmaster Tasks
1 1 cooking food.
2 1 Programing 2 hours
3 1 Attending meeting
4 2 Driving car
5 2 hangout with friends
Have tried this query
select tasks + ' , ' as 'data()' from tb_tasks for xml path('')
Gives Output
XML
cooking food , Programing 2 hours , Attending meeting , Driving car , hangout with friends ,
I need output like
id Name grade task_date tasksDetails
1 John A 2012-02-13 10:40:00.000 1)cooking food, 2)Programing 2 hours, 3)Attending meeting
2 Tom B 2012-02-13 10:40:00.000 1) Driving car, 2)hangout with friends
Query i tried
select a.name,a.task_date,b.tasks =replace(select (CONVERT(VARCHAR,(ROW_NUMBER() OVER(ORDER BY id DESC)))) + ') ' + tasks + ' , ' as 'data()'
from tb_tasks for xml path(''))
from tb_master a inner join tb_tasks b
on a.id=b.id_tbmaster
Thanks in advance
This query will create requested list of activities per tb_master. Two pointers: one should match ordering in row_number() over() and in query to get consistent results, and number 3 in last row of OUTER APPLY is number of characters in separator (in this case, ' , '). If you change separator you need to adjust this number.
select a.name,a.task_date, b.taskList
from tb_master a
OUTER APPLY
(
select stuff ((select ' , '
+ CONVERT(VARCHAR(10), ROW_NUMBER()
OVER(ORDER BY id DESC))
+ ') '
+ tasks
from tb_tasks b
where a.id = b.id_tbmaster
order by id desc
for xml path (''))
, 1, 3, '') taskList
) b
Live demo is at Sql Fiddle.

Return Multi Row DataSet as Single Row CSV without Temp Table

I'm doing some reporting against a silly database and I have to do
SELECT [DESC] as 'Description'
FROM dbo.tbl_custom_code_10 a
INNER JOIN dbo.Respondent b ON CHARINDEX(',' + a.code + ',', ',' + b.CC10) > 0
WHERE recordid = 116
Which Returns Multiple Rows
Palm
Compaq
Blackberry
Edit *
Schema is
Respondent Table (At a Glance) ...
*recordid lname fname address CC10 CC11 CC12 CC13*
116 Smith John Street 1,4,5, 1,3,4, 1,2,3, NULL
Tbl_Custom_Code10
*code desc*
0 None
1 Palm
10 Samsung
11 Treo
12 HTC
13 Nokia
14 LG
15 HP
16 Dash
Result set will always be 1 row, so John Smith: | 646-465-4566 | Has a Blackberry, Palm, Compaq | Likes: Walks on the beach, Rainbows, Saxophone
However I need to be able to use this within another query ... like
Select b.Name, c.Number, d.MulitLineCrap FROM Tables
How can I go about this, Thanks in advance ...
BTW I could also do it in LINQ if any body had any ideas ...
Here is one way to make a comma-separated list based on a query (just replace the query inside the first WITH block). Now, how that joins up with your query against b and c, I have no idea. You'll need to supply a more complete question - including specifics on how many rows come back from the second query and whether "MultilineCrap" is the same for each of those rows or if it depends on data in b/c.
;WITH x([DESC]) AS
(
SELECT d FROM (VALUES('Palm'),('Compaq'),('Blackberry')) AS x(d)
)
SELECT STUFF((SELECT ',' + [DESC]
FROM x
FOR XML PATH(''), TYPE).value(N'./text()[1]', N'varchar(max)'),1,1,'');
EDIT
Given the new requirements, perhaps this is the best way:
CREATE FUNCTION dbo.GetMultiLineCrap
(
#s VARCHAR(MAX)
)
RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE #x VARCHAR(MAX) = '';
SELECT #x += ',' + [desc]
FROM dbo.tbl_custom_code_10
WHERE ',' + #s LIKE '%,' + RTRIM(code) + ',%';
RETURN (SELECT STUFF(#x, 1, 1, ''));
END
GO
SELECT r.LName, r.FName, MultilineCrap = dbo.GetMultiLineCrap(r.CC10)
FROM dbo.Respondent AS r
WHERE recordid = 116;
Please use aliases that make a little bit of sense, instead of just serially applying a, b, ,c, etc. Your queries will be easier to read, I promise.

Resources