I am trying to combine rows from one table with my query in MS SQL on server 2008. I pulled this code off here I believe. This almost fits my needs but it is grouping the serial numbers off of SOPartsUsed but I need it to group based off tblServiceOrders.ProjectKeyID. Any help would be greatly appreciated I don't know much about SQL. I will leave a more detailed explanation of what I am trying to accomplish below.
SELECT
p1.ItemID, SerialNumbers AS SerialNumber
FROM
tblSOPartsUsed p1 INNER JOIN
tblServiceOrders p2 ON p1.SONumber = p2.SONumber
CROSS APPLY
(SELECT
stuff
((SELECT ',' + p3.SerialNumber
FROM tblSerialNumbers p3
WHERE p3.FKSOPartsUsed = p1.SOPartsUsedKeyID
ORDER BY SerialNumber FOR XML PATH(''), TYPE ).value('.', 'varchar(max)'), 1, 1, '')
) D (SerialNumbers)
WHERE (p1.QuantityFilled > 0) AND (p2.ProjectKeyID = 385)
GROUP BY p1.ItemID, SerialNumbers, p2.ProjectKeyID
ORDER BY p1.ItemID
I have a table with serial numbers a table with parts used on a service order and a service order table.
tblSerialNumbers -> tblSOPartsUsed -> tblServiceOrders
tblSerialNumbers
itemID SerialNumber FKSOPartsUsed
1 1444 233
1 1555 234
1 1666 236
1 1999 237
1 1888 238
1 2222 239
1 2121 240
tblSOPartsUsed
itemID SOPartsUsed SONumber QuantityFilled
1 233 SO544 5
1 234 SO544 7
1 236 SO544 7
1 237 SO577 7
1 238 SO577 7
1 239 SO581 7
1 240 SO580 7
tblServiceOrders
SOnumber ProjectKeyID
SO544 PJ366
SO577 PJ366
SO580 PJ111
SO581 PJ111
What I would like
itemID ProjectKeyID SerialNumber
1 PJ366 1444,1555,1666,1999,1888
What I get
itemID ProjectKeyID SerialNumber
1 PJ366 1444,1555,1666
1 PJ366 1999,1888
I am trying to group serial numbers and item id's by ProjectKeyID found in tblServiceOrders. Right now the query above works but it is grouping ItemID's on the tblSOPartsUsed and want to group on ProjectKeyID.
Thanks for any help.
SELECT itemID ,
ProjectKeyID ,
( SELECT SerialNumber + ', ' AS 'data()'
FROM dbo.tblSOPartsUsed u
JOIN tblSerialNumbers nbr ON u.SOPartsUsed = nbr.FKSOPartsUsed
WHERE SONumber IN ( SELECT SOnumber
FROM dbo.tblServiceOrders
WHERE ProjectKeyID = tso.ProjectKeyId )
AND itemID = tso.itemID
FOR
XML PATH('')
)
FROM ( SELECT DISTINCT
c.itemID ,
ProjectKeyId
FROM dbo.tblServiceOrders a
JOIN dbo.tblSOPartsUsed b ON a.SOnumber = b.SONumber
JOIN dbo.tblSerialNumbers c ON b.SOPartsUsed = c.FKSOPartsUsed
) tso
I don't think I totally understand what you're trying to accomplish with itemID - having only one distinct value in the sample makes it hard to verify results - but this might get you closer
try this
SELECT
p1.ItemID, p2.ProjectKeyID,D.SerialNumbers AS SerialNumber
FROM
tblSOPartsUsed p1 INNER JOIN
tblServiceOrders p2 ON p1.SONumber = p2.SONumber
CROSS APPLY
(SELECT
stuff
((SELECT ',' + p3.SerialNumber
FROM tblSerialNumbers p3
WHERE p3.ItemID = p1.ItemID
ORDER BY SerialNumber FOR XML PATH(''), TYPE ).value('.', 'varchar(max)'), 1, 1, '')
) D (SerialNumbers)
WHERE (p1.QuantityFilled > 0) AND (p2.ProjectKeyID = 'PJ366')
GROUP BY p1.ItemID, p2.ProjectKeyID, SerialNumbers
ORDER BY p1.ItemID
Related
I have a table which contains data in this format.
ProductID ShipId
11 1
11 2
11 3
22 1
22 2
33 1
33 2
Now I want only the distinct product ids where ship id 3 is not associated.
Output should be
22,33 only.
I have used this query but it throws error.
Select distinct productid from X_product_ship group by productid having shipid <> 3
Please help.
Use a subquery in the where clause to exclude the products that has a shipid of three.
select distinct P1.ProductID
from dbo.X_product_ship as P1
where P1.ProductID not in (
select P2.ProductID
from dbo.X_product_ship as P2
where P2.ShipId = 3
)
SQL Fiddle
Or you could get creative in the having clause using a case statement.
select P.ProductID
from dbo.X_product_ship as P
group by P.ProductID
having max(case when P.ShipId = 3 then 1 else 0 end) = 0
SQL Fiddle
Hi I have a query returning this
member_id question_variable response_id label
----------- -------------------------------------------------- ----------- ----------------------------
35 area 15 Sydney (Metro)
35 relationship_status 8 Single
35 education 31 Bachelor Degree
35 house_hold_income 4 $75,001 to $100,000
35 pets 36 Dog
35 pets 37 Fish
How do i detect duplicate results such as pets and have response_id = 36,37 and label = Dog, Fish
like so
member_id question_variable response_id label
----------- -------------------------------------------------- ----------- ----------------------------
35 area 15 Sydney (Metro)
35 relationship_status 8 Single
35 education 31 Bachelor Degree
35 house_hold_income 4 $75,001 to $100,000
35 pets 36,37 Dog,Fish
You have to use the keyword STUFF to get the above result.
QUERY:
SELECT DISTINCT T1.MEMBER_ID,T1.QUESTION_VARIABLE,
STUFF((SELECT DISTINCT ',' + T2.RESPONSE_ID
FROM TEST T2
WHERE T1.QUESTION_VARIABLE = T2.QUESTION_VARIABLE
FOR XML PATH('') ),1,1,'') AS RESPONSE_ID,
STUFF((SELECT DISTINCT ',' + T2.LABEL
FROM TEST T2
WHERE T1.QUESTION_VARIABLE = T2.QUESTION_VARIABLE
FOR XML PATH('') ),1,1,'') AS LABEL
FROM TEST T1
;
HERE IS THE LINK TO SQL FIDDLE
http://sqlfiddle.com/#!3/64515/3
This is can be achieved in the following way as well. I haven't got a chance to test this against large data set.
If you want to check the performance, please turn on the following
SET STATISTICS IO ON
SET STATISTICS TIME ON
Query:
SELECT Main.member_id,
Main.question_variable,
STUFF(SubResponse.response_id,1,1,'') AS response_id,
STUFF(SubLebel.label,1,1,'') AS label
FROM Member Main
CROSS APPLY
(
SELECT ',' + response_id
FROM Member
WHERE member_id = Main.member_id AND question_variable = Main.question_variable
FOR XML PATH('')
) SubResponse (response_id)
CROSS APPLY
(
SELECT ',' + label
FROM Member
WHERE member_id = Main.member_id AND question_variable = Main.question_variable
FOR XML PATH('')
) SubLebel (label)
GROUP By Main.member_id,
Main.question_variable,
SubResponse.response_id,
SubLebel.label
SELECT member_id, question_variable, count(*)
FROM MyData
GROUP BY member_id, question_id
HAVING COUNT(*) > 1
Below are the 3 tables
QuotationMaster
QuoteID QuoteNo CustomerName
-----------------------------
1 Q1 Name1
2 Q2 Name2
3 Q3 Name3
4 Q4 Name4
5 Q5 Name5
QuoteItemDetails : one quote can have many items
QuoteItemID QuoteID ItemCode ItemID
---------------------------------------------
1 1 100 1
1 1 200 2
2 2 200 2
QuoteBatchDetails : one QuoteItem can have many batches of QuoteID and ItemID are the common columns. BatchNo is varchar
QuotebatchID QuoteID BatchNo ItemID
---------------------------------------------
1 1 A 1
2 1 B 1
3 1 C 2
4 2 E 2
5 2 F 2
I want the result as
QuoteID QuoteNo CustName ItemCode BatchNo
-------------------------------------------------
1 Q1 Name1 100 A,B
1 Q1 Name1 200 C
2 Q2 Name2 200 E,F
I want to create a procedure which takes QuoteID as parameter of INT type and get the result as above.
The only problem I am facing is to concatenate the BatchNo which depends on ItemID and further on QuoteID.
Using the below query I am able to concatenate the BatchNo for a particular ID but I am not sure how to add this to the main procedure, when I do that errors pops up like subquery returns more than one value.I understand because for every quote there can be more than 1 item.
select
ID.QuoteID,ID.ItemID,
stuff((select ', ' + BatchNo
from SD_QuoteBatchDetails BD where ID.ItemID=BD.ItemID and ID.QuoteID=BD.QuoteID
for xml path('')),
1,2,'') [Values]
from SD_QuoteItemDetails QID,SD_QuoteBatchDetails ID where ID.QuoteID=QID.QuoteID
group by ID.ItemID,ID.QuoteID
Can anyone provide a query for the same.
SELECT b.QuoteItemID,
a.QuoteNo,
a.CustomerName,
b.ItemCode,
c.BatchList
FROM QuotationMaster a
INNER JOIN QuoteItemDetails b
ON a.QuoteID = b.QuoteID
INNER JOIN
(
SELECT
QuoteID,
ItemID,
STUFF(
(SELECT ', ' + BatchNo
FROM QuoteBatchDetails
WHERE QuoteID = a.QuoteID AND
ItemID = a.ItemID
FOR XML PATH (''))
, 1, 1, '') AS BatchList
FROM QuoteBatchDetails AS a
GROUP BY QuoteID, ItemID
) c ON b.QuoteID = c.QuoteID AND
b.ItemID = c.ItemID;
SQLFiddle Demo
This question already has answers here:
How to concatenate text from multiple rows into a single text string in SQL Server
(47 answers)
Closed 9 years ago.
i have a table like this
ID NAME Amount
1 cal 100
2 cal 200
3 cal 300
4 cal 400
1 ser 500
2 ser 600
5 ser 700
i want to write a select query so that i wil get the resul like this
ID NAME Amount
1 cal and ser 600
2 cal and ser 800
3 cal 300
4 cal 400
5 ser 700
here i need to group by id and sum of amount and concat the string name with same id and differnet name
this will work with sql-server 2008
SELECT p1.ID,
( SELECT NAME + ' and '
FROM YourTable p2
WHERE p2.ID = p1.ID
ORDER BY NAME
FOR XML PATH('') ) AS Name,
sum(Amount)
FROM YourTable p1
GROUP BY ID ;
SELECT p1.ID,
STUFF(( SELECT ' and ' + NAME
FROM YourTable p2
WHERE p2.ID = p1.ID
ORDER BY NAME
FOR XML PATH('') )
, 1, 5, '' ) AS Name,
sum(Amount)
FROM YourTable p1
GROUP BY ID
From Vikram answer
I add stuff for my result.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Combining rows of queried results by unique identifier?
I have two tables in Sql Server 2008, like below
Table1
DealNum DealVresion Value
1000 1 100
1000 2 200
1000 3 150
1000 4 130
1001 2 70
1003 5 160
1003 0 120
Table 2
DealNum DealVersion Name
1000 1 John
1000 1 Bob
1000 2 John
1000 2 Merle
1000 3 Bob
1000 3 Bob
1000 5 Bob
1001 2 Smith
1001 2 stone
1002 8 Andrew
1003 5 Smith
1003 0 Martin
1003 0 Narine
Now I want a left join on these two tables based on
(T1.Dealnum= T2.Dealnum) and (T1.Deal Version = T2.Deal Version)
and I want the Name from Table2 to be concatenated so that it won't show any duplicates in DealNum.
Result Required:
DeaLNum Deal Version Value Name
1000 1 100 Jhon,Bob
1000 2 200 John,Merle
1000 3 150 Bob
1000 4 130 NULL
1001 2 70 Smith,Stone
1003 0 120 Martin,Narine
1003 5 160 Smith
It has to concatenate the names column for the DealNum and version.
If the same dealNum and Version has the same name then no need to Concatenate(ex: 1000 - 3)
Thanks In advance
Harry
You can do this by creating a user defined function, don't know if it can be done in a single select statement:
create function getNameList(#dealnum int, #dealversion int) returns nvarchar(max)
begin
declare #name varchar(max)
select #name = coalesce(#name + ', ','') + name
from (select distinct name from table2 where dealnum = #dealnum and dealversion = #dealversion) t1
return #name
end
then:
select distinct
t1.dealNum,
t1.dealVersion,
t1.value,
dbo.getNameList(t1.dealNum, t1.dealversion)
from table1 t1 join table2 t2 on t1.dealnum = t2.dealnum and t1.dealversion = t2.dealversion
try this:
with cte as (
select distinct T1.DealNum [T1_DealNum],T1.DealVresion [T1_DealVresion],
T1.Value [T1_Value],
T2.DealNum [T2_DealNum],T2.DealVresion [T2_DealVresion],T2.Name [T2_Name]
from Table1 T1 left outer join Table2 T2
on (T1.Dealnum= T2.Dealnum) and (T1.DealVresion = T2.DealVresion)
)
select [T1_DealNum],[T1_DealVresion],[Name]=
STUFF((SELECT ', ' + [T2_Name]
FROM cte b
WHERE a.[T1_DealNum]= b.[T2_DealNum]
and a.[T1_DealVresion] = b.[T2_DealVresion]
FOR XML PATH('')), 1, 2, '')
FROM cte a
GROUP BY [T1_DealNum],[T1_DealVresion]
order by [T1_DealNum],[T1_DealVresion]
;WITH y AS
(
SELECT DealNum, DealVersion, Name = STUFF((SELECT ',' + y2.Name
FROM dbo.Table2 AS y2
WHERE y2.DealNum = y.DealNum AND y2.DealVersion = y.DealVersion
GROUP BY y2.Name
FOR XML PATH(''),
TYPE).value(N'./text()[1]', N'nvarchar(max)'), 1, 1, '')
FROM dbo.Table2 AS y
)
SELECT x.DealNum, x.DealVersion, x.Value, y.Name
FROM dbo.Table1 AS x
LEFT OUTER JOIN y
ON x.DealNum = y.DealNum
AND x.DealVersion = y.DealVersion
GROUP BY x.DealNum, x.DealVersion, x.Value, y.Name;