Concatenate a single Column value depending on Condition - sql

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

Related

Concatenate row values into single row per group

I have a problem.
Table-1 Name : InvoiceDetail
InvoiceNo StockCode Piece
---------- ----------- ------
1 CP-001 10
1 CP-002 15
2 CP-001 18
2 MN-001 18
Table-2 Name : Stock
StockCode StockName
----------- -----------
CP-001 Computer-A
CP-002 Computer-B
MN-001 Monitor-A
Expected Result
InvoiceNo Description TotalPiece
---------- ----------------------- ----------
1 Computer-A, Computer-B 25
2 Computer-A, Monitor-A 36
I wrote the below query
Query
SELECT InvoiceNo,
(select StockName + '-' from Stock
where StockCode = Results.StockCode
order by StockName
FOR XML PATH('')) AS Description,
SUM(Piece) AS TotalPiece
FROM InvoiceDetail Results
GROUP BY InvoiceNo, Results.StockCode
ORDER BY InvoiceNo
And results
InvoiceNo Description TotalPiece
1 Computer-A- 10
1 Computer-B- 15
2 Computer-A- 18
2 Monitor-A- 18
Whats wrong?
Perform the group by separately in a CTE, and then you can safely concatenate the description as a separate step:
with InvoiceGroupings as (
select t.InvoiceNo,
sum(t.Piece) as TotalPiece
from InvoiceDetail t
group by t.InvoiceNo)
select g.InvoiceNo,
stuff((select ', ' + s.StockName
from InvoiceDetail i
join Stock s
on i.StockCode = s.StockCode
where i.InvoiceNo = g.InvoiceNo
order by s.StockName
for xml path('')),1,2,'') as Description,
g.TotalPiece
from InvoiceGroupings g
order by g.InvoiceNo
SQL Fiddle Demo

Oracle SQL No Data in series

I have a query result that is almost perfect except for the fact that in the result I don't always have a complete series in my muli-series data that I am trying to eventually show in a report and chart.
NAME MONTH COST
----------------------------------------
name1 2 100
name1 3 80
name2 1 60
name3 2 30
----------------------------------------
Here is query:
select Name, month, count(*) as cost
from table1
group by name, month
order by month, name
What I have here isn't one simple set of data, but a series of data. For each month, I have a set of users and sales.
I can fix this on my application side by doing a few loops and getting the distinct values for Name and Month.
I'd like to learn how to create my Oracle query to get a result set that looks something like this
NAME MONTH COST
----------------------------------------
name1 1 0
name1 2 100
name1 3 80
name2 1 60
name2 2 0
name2 3 0
name3 1 0
name3 2 30
name3 3 0
----------------------------------------
You can do this with a cross join and then a left outer jon:
select n.name, m.month, coalesce(t.cost, 0) as cost
from (select distinct name from table t) n cross join
(select distinct month from table t) m left join
table t
on t.name = n.name and t.month = m.month
order by n.name, m.month;

How to Add Order to an existing table?

I have table called Products. Let say this is my table,
ID Name ParentID
-- --- --------
1 a NULL
2 b NULL
3 a1 1
4 a2 1
5 b2 2
6 b2 2
Now I need to add [Order] Column with respect to ParentID,
ID Name ParentID Order
-- --- -------- ----
1 a NULL NULL
2 b NULL NULL
3 a1 1 1
4 a2 1 2
5 b2 2 1
6 b2 2 2
Creating [Order] is trivial but inserting record is a bit tricky part
UPDATE [Products]
SET [Products].[Order] = PTT.[Order]
FROM
[Products]
INNER JOIN (SELECT ID, ROW_NUMBER() OVER (PARTITION BY PT.ParentID ORDER BY ID) AS [Order]
FROM [Products] PT
WHERE PT.ParentID IS NOT NULL) AS PTT ON PTT.ID = [Products].ID

Sql Query help needed for product relation

I have one product table with following info.
ID ProductId Name OtherData
1 0 A data1
2 0 B data2
3 1 A1 NULL
4 1 A2 NULL
I need all data with detail ProductId is relationship with ID column.
I need result like below
ID ProductId Name OtherData
1 0 A data1
2 0 B data2
3 1 A1 data1
4 1 A2 data1
What kind of join or query I should use?
SELECT s.ID, s.ProductId, s.Name,
OtherData = COALESCE(s.OtherData, r.OtherData)
FROM dbo.Products AS s
LEFT OUTER JOIN dbo.Products AS r
ON s.ProductId = r.ID;

SQL Command combining rows from a field

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