How to Add Order to an existing table? - sql

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

Related

How to set unique ID with ID of group in it?

I have this table:
ID
Value
Gr_Id
Gr_Value
NULL
A
1
A
NULL
B
1
A
NULL
C
2
B
NULL
D
2
B
NULL
E
2
B
NULL
F
3
C
And I need id like this
ID
Value
Gr_Id
Gr_Value
101
A
1
A
102
B
1
A
201
C
2
B
202
D
2
B
203
E
2
B
301
F
3
C
I need unique ID for each row but with ID of group on beginning
if maximum number per group is 99 then :
select gr_id * 100 + row_number() over (partition by Gr_id order by gr_value) as Id , *
from tablename

SQL Join on the same table

Table T
P_ID | Name | Status
1 ABC Ordered
1 ABC Processing
1 ABC Imported
2 PQR Ordered
2 PQR Failed
3 LMN Ordered
Expected Result
Table T
P_ID | Name | Status
2 PQR Ordered
2 PQR Failed
3 LMN Ordered
I am not getting the correct result with the following query. I want to find all the records that have status Ordered but do not have the status "Imported".
select c1.P_ID,c1.Name,c2.Status
from T c1, T c2
where c1.P_ID = c2.P_ID
c1.Status="Ordered" and c2.status != "Imported"
Using Oracle 11g database
select c1.P_ID, c1.Name, c1.Status
from T c1
where c1.Status = 'Ordered' and
NOT EXISTS (SELECT 1
FROM T c2
WHERE c1.P_ID = c2.P_ID and c2.status = 'Imported'
);
You can use the following code:
select c1.P_ID,c1.Name,c1.Status
from T c1
where exists (select 1
from T
where P_ID = c1.P_ID
and Status="Ordered"
and rownum = 1)
and not exists (select 1
from T
where P_ID = c1.P_ID
and Status="Imported"
and rownum = 1)

SQL - Find the Top Level Parent and Multiply Quantities

I have two tables which track part numbers as well as the hierarchy of assemblies.
Table: Config
ConfigNum AssemblyNum Qty
1 A 1
1 B 2
1 C 2
2 A 1
2 C 1
Table: SubAssembly
SubAssembly PartNum Qty
A AA 2
A BB 4
A CC 2
A DD 4
B EE 4
B FF 8
AA AAA 2
I would like to create a flat version of these tables which shows the ConfigNum (Top level parent) with all associated assembly and part numbers, for each ConfigNum in the Config table. The column Config.AssemblyNum is equivalent to SubAssembly.SubAssembly.
The Subassembly table shows the partent to child relation ship between parts. For example Assembly 'A' has a child assembly 'AA'. Since 'AA' exists in the SubAssembly Column is it self an assembly and as you can see it has a child part 'AAA'. 'AAA' does not exist in the SubAssemly columns therefore it is the last child in the series.
I would also like to have an accurate quantity count of each part based on multiplying of parent to child down the chain.
For example in the output:
(Total Qty of AAA) = (Qty A) x (Qty AA) x (Qty AAA)
4 = 1 x 2 x 2
Example Output table: (for Config 1)
ConfigNum SubAssembly PartNum TotalQty
1 A AA 2
1 A BB 4
1 A CC 2
1 A DD 4
1 B EE 8
1 B FF 16
1 A AAA 4
Any suggestion on how to complete this task would be greatly appreciated.
EDIT: I have been able to create this code based on suggestions made in the answers.
I am still having trouble getting the quantities to multiply down.
I have received the error "Types don't match between the anchor and the recursive part in column "PartQty" of recursive query "RCTE"."
;WITH RCTE (AssemblyNum, PartNum, PartQty, Lvl) AS
(
SELECT AssemblyNum, PartNum, PartQty, 1 AS Lvl
FROM SP_SubAssembly r1
WHERE EXISTS (SELECT * FROM SP_SubAssembly r2 WHERE r1.AssemblyNum = r2.PartNum)
UNION ALL
SELECT rh.AssemblyNum, rc.PartNum, (rc.PartQty * rh.PartQty), Lvl+1 AS Lvl
FROM dbo.SP_SubAssembly rh
INNER JOIN RCTE rc ON rh.PartNum = rc.AssemblyNum
)
SELECT CB.ID, CB.ConfigNum, CB.PartNum, CB.PartQty, r.AssemblyNum, r.PartNum, SUM(r.PartQty * COALESCE(CB.PartQty,1)) AS TotalQty
FROM SP_ConfigBOM CB
FULL OUTER JOIN RCTE r ON CB.PartNum = r.AssemblyNum
WHERE CB.ConfigNum IS NOT NULL
ORDER BY CB.ConfigNum
Thanks,
For this problem I think you must use a recursive query. In fact I think SubAssembly table should have some ProductID field other than SubAssembly to easily identify the main product that contains assemblies.
You can find a similar example in SLQ Server documentation.
Can check it here: http://rextester.com/FQYI80157
Change the Qty in Config table to change the final result.
create temp table t1 (cfg int, part varchar(10), qty int);
create temp table t2 (part varchar(10), sasm varchar(10), qty int);
insert into t1 values (1,'A',2);
insert into t2 values ('A','AA',2);
insert into t2 values ('A','BB',4);
insert into t2 values ('A','CC',2);
insert into t2 values ('A','DD',4);
insert into t2 values ('AA','AAA',2);
WITH cte(sasm, part, qty)
AS (
SELECT sasm, part, qty
FROM #t2 WHERE part = 'A'
UNION ALL
SELECT p.sasm, p.part, p.qty * pr.qty
FROM cte pr, #t2 p
WHERE p.part = pr.sasm
)
SELECT #t1.cfg, cte.part, cte.sasm, SUM(cte.qty * COALESCE(#t1.qty,1)) as total_quantity
FROM cte
left join #t1 on cte.part = #t1.part
GROUP BY #t1.cfg, cte.part, cte.sasm;
This is the result:
+------+------+----------------+
| part | sasm | total_quantity |
+------+------+----------------+
| A | AA | 4 |
+------+------+----------------+
| A | DD | 8 |
+------+------+----------------+
| AA | AAA | 4 |
+------+------+----------------+
| A | BB | 8 |
+------+------+----------------+
| A | CC | 4 |
+------+------+----------------+
insert into #Temp
SELECT A.[ConfigNum] ,
A.[AssemblyNum],
B.[PartNum],
A.[Qty],
A.QTY * B.Qty TotalQty
INTO #Temp
FROM [Config] A,
[SubAssembly] B
WHERE A.[AssemblyNum] = B.[SubAssembly]
SELECT A.[ConfigNum] ,
A.[AssemblyNum],
A.[PartNum],
A.[Qty],
A.TotalQty
FROM #Temp A
union
SELECT A.[ConfigNum] ,
A.[AssemblyNum],
B.[PartNum],
A.[Qty],
A.TotalQty * B.Qty
FROM #Temp A,
[SubAssembly] B
WHERE
A.[PartNum] = B.[SubAssembly]

Concatenate a single Column value depending on Condition

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

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;