SELECT with derived csv value included - sql

I want to have a SELECT that as part of list of return fields would also include a csv of multiple values from another table.
I have code working to determine the CSV from here:
SQL Server 2008 Rows to 1 CSV field
But i am not able to get a working JOIN with the csv value, or get at the id field of the derived csv values.
My two tables are:
job (id,title,location)
skills(id, jobID, skillName, listOrder)
I want to do a select * from job with each job record having its own derived skills
basically result should be:
1,dba,texas, [sql,xml,rdp] <-- skills for jobid=1

This seems to do, what you are looking for:
SELECT
J.id
, J.title
, J.location
, '[' + STUFF ((SELECT ',' + S.skillName
FROM Skills S
WHERE
J.id = S.jobID
ORDER BY S.listOrder
FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)')
, 1, 1, '') + ']' skillSet
FROM Job J
GROUP BY J.id, J.title, J.location
;
See it in action: SQL Fiddle
Please comment, if and as this requires adjustment / further detail.

Related

How to combine the column values from the same table with condition in sql select query

I want to combine the Currency field by comparing Config and Product Column. If both field is repeated with duplicate values but different currency, the combine the currency into single row as you see in the screenshot.
I tried the code like
Select DISTINCT LC.Config, LC.Product, CONCAT(LC.Currency,',',RC.Currency) as Currencies FROM [t_LimitCurrency] LC INNER JOIN [t_LimitCurrency] RC ON LC.[Config] = RC.[Config] AND LC.Product = RC.Product
Please let me know, how to write select statement for this scenario.
Below Code should do the trick. I am using XML Path but you can use String_AGG in latest version of sql server
select distinct Config,Product,
STUFF((SELECT ' ,' + CAST(Currency AS VARCHAR(max)) [text()]
FROM (
SELECT Currency
FROM Yourtable b
WHERE a.Config=b.Config and a.product=b.product
) ap
FOR XML PATH(''), TYPE)
.value('.','NVARCHAR(MAX)'),1,2,' ') Currency
from Yourtable a
EDIT 1 : for latest version of sql server code should be like below
select distinct Config,Product,
(SELECT
STRING_AGG(CONVERT(NVARCHAR(max),Currency), ',')
FROM YourTable b WHERE a.Config=b.Config and a.product=b.product)
Currency
from Yourtable a

How to retrieve single column separated by comma with multiples values, and apply join in sql

I have the following two tables in sql.I want to get the calendarId from calenderschedule and join with calendar table to get the calendarcode for each productId. Output format is described below.
MS SQL Server 2012 version string_split is not working. Please help to get the desired output.
Table1: calenderschedule
productid, calendarid
100 1,2,3
200 1,2
Table2: calendar
calendarid, calendarCode
1 SIB
2 SIN
3 SIS
Output:
productId, calendarCode
100 SIB,SIN,SIS
200 SIB,SIN
You can normalize the data by converting to XML and then using CROSS APPLY to split it. Once it's normalized, use the STUFF function to combine the calendar codes into a comma-separated list. Try this:
;WITH normalized_data as (
SELECT to_xml.productid
,split.split_calendarid
FROM
(
SELECT *,
cast('<X>'+replace(cs.calendarid,',','</X><X>')+'</X>' as XML) as xmlfilter
FROM calendarschedule cs
) to_xml
CROSS APPLY
(
SELECT new.D.value('.','varchar(50)') as split_calendarid
FROM to_xml.xmlfilter.nodes('X') as new(D)
) split
) select distinct
n.productid
,STUFF(
(SELECT distinct ', ' + c.calendarCode
FROM calendar c
JOIN normalized_data n2 on n2.split_calendarid = c.calendarid
WHERE n2.productid = n.productid
FOR XML PATH ('')), 1, 1, '') calendarCode
from normalized_data n
I feel like this solution is a bit overly complex, but it's the only way I got it to work. If anybody knows how to simplify it, I'd love to hear some feedback.

SQL Query - Copy Data into One Field

I have a SQL database and I am writing a query:
SELECT *
FROM Consignments
INNER JOIN OrderDetail
ON Consignments.consignment_id = OrderDetail.consignment_id
INNER JOIN UserReferences
ON OrderDetail.record_id = UserReferences.record_id
WHERE Consignments.despatch_date = '2020-04-23'
Within the first column is:consignment_id [this is from the Consignments table]In the final column is:senders_reference [this is from the UserReferences table]
Now - the issue I have is - that when I am running the query to pick up all consignments for a particular date - it is displaying multiple rows (with duplicated consignment_id) when there are multiple senders references within the database.
If there is one senders reference number - then there is only 1 row.
This makes sense - because within the front-end for the database the user can enter 1 or more senders references.
Now - what I would like to do is to amend my query for the resulting data to only display 1 row for all consignments and if there are multiple senders reference numbers - to have them within the one field, separated by commas.
Is this doable from the query stage?
Or if not - after export, is it possible to develop a bat file to do the same thing?
For reference - this is what I mean - this is the result I am getting at the moment:
This is what I need:
You can use older style with the help of for xml :
select t.consignment_id,
stuff((select ', ' +convert(varchar(255), t1.sender_reference)
from table t1
where t1.consignment_id = t.consignment_id
for xml path('')
), 1, 1, ''
) as senders_reference
from (select distinct consignment_id from table t) t;
Edit : You can use CTE :
with cte as (
<your query>
)
select t.consignment_id,
stuff((select ', ' +convert(varchar(255), t1.sender_reference)
from cte t1
where t1.consignment_id = t.consignment_id
for xml path('')
), 1, 1, ''
) as senders_reference
from (select distinct consignment_id from cte t) t;
You seem to want to use the STRING_AGG function.
This answer covers it nicely
ListAGG in SQLSERVER

Removing duplicate concatenated values in a sql column

I am updating a product bin location in our database using the reference text from a stock count we recently did. Some of the products have multiple bin locations, so I am using this SQL to pull all the bin locations into a table:
SELECT
SCT.ProductID,
STUFF ((SELECT ',' + ReferenceText
FROM StockCounttickets SCT2
WHERE SCT2.ProductId = SCT.ProductID
AND SCT2.StockCountID = '10873'
ORDER BY ProductID
FOR XML PATH(''), TYPE).value('.', 'varchar(max)'), 1, 1, '') AS Products
FROM
StockCountTickets SCT
WHERE
SCT.StockCountID = '10873'
GROUP BY
ProductID ;
I am getting the result I want, except for some of the products were counted twice in the same place, so some of the results have the same value twice
Is there any way to get rid of the duplicates?
Presumably, you mean the duplicates in the concatenated list.
Well, you can just remove the duplicates using select distinct or group by:
SELECT SCT.ProductID,
STUFF( (SELECT DISTINCT ',' + SCT2.ReferenceText
FROM StockCounttickets SCT2
WHERE SCT2.ProductId = SCT.ProductID AND
SCT2.StockCountID = 10873
ORDER BY SCT2.ProductID
FOR XML PATH(''), TYPE).value('.', 'varchar(max)'
), 1, 1, '') AS Products
FROM (SELECT DISTINCT SCT.ProductId
FROM StockCountTickets SCT
WHERE SCT.StockCountID = 10873
) SCT;
Notes:
In a correlated subquery, you should qualify all column references, always, to avoid errors.
Assuming StockCountID is a number, don't use quotes for the comparison.
I prefer to generate the distinct rows in the subquery. I believe this is a performance gain.

SQL Server : combine two rows into one

I want to write a query which will display the following result
FROM
ID Contract# Market
1 123kjs 40010
1 123kjs 40011
2 121kjs 40098
2 121kjs 40099
TO
ID Contract# Market
1 123kjs 40010,40011
2 121kjs 40098,40099
Try out this query, I use GROUP_CONCAT to turn column fields into 1 row field.
Also notice that you should rename the FROM clause with the name of your table.
SELECT ID,Contract#, GROUP_CONCAT(Market SEPARATOR ',')
FROM nameOfThatTable GROUP BY ID;
Try this out. I used PIVOT to solve it.
SELECT
ID,
Contract#,
ISNULL(CONVERT(varchar,[40010]) + ',' + CONVERT(varchar,[40011]),
CONVERT(varchar,[40098]) + ',' + CONVERT(varchar,[40099])) AS Market FROM
( SELECT * FROM ContractTable) AS A
PIVOT(MIN(Market) FOR Market IN ([40010],[40011],[40098],[40099])) AS PVT
ORDER BY ID
You can use ', ' + CAST(Market AS VARCHAR(30)) in sub-query and join Id and Contract# of sub-query with outer query to get values of Market as Comma Separated Values for each Id and Contract#.
SELECT DISTINCT ID,Contract#,
SUBSTRING(
(SELECT ', ' + CAST(Market AS VARCHAR(30))
FROM #TEMP T1
WHERE T2.Id=T1.Id AND T2.Contract#=T1.Contract#
FOR XML PATH('')),2,200000) Market
FROM #TEMP T2
Click here to view result
Note
.........
If you want to get CSV values for Id only, remove T2.Contract#=T1.Contract# from sub-query.