I have two tables, Table A & Table B
Table A:
G.R.N ITEM QUANTITY
--------------------------
1 ABC001 150
1 CBD001 150
1 SDB001 100
Table B:
DELIVERY ITEM QUANTITY
-------------------------------
34 ABC001 50
35 ABC001 40
36 ABC001 60
37 CBD001 50
38 CBD001 40
39 CBD001 10
Is it possible to get desired output like this:
G.R.N ITEM QUANTITY DELIVERY ITEM QUANTITY DIFFERENCE
1 ABC001 150 34,35,36 ABC001 150 0
1 CBD001 150 37,38,39 CBD001 100 50
1 SDB001 100 100
for recent version of sql-server (sql-server 2017)
You could try using left join, sum and group by
select A.GRN
, A.ITEM
, A.QUANTITY
, STRING_AGG(B.DELIVERY,',' ) DELIVERY
, B.ITEM
, SUM(B.QUANTITY )
, A.QUANTITY - SUM(B.QUANTITY ) QUANTITY_DIFFERENCE
from tableA A
left JOIN tableB B ON A.ITEM = B.ITEM
group by A.ITEM
You can join the tables using the item column. If you perform a left join, then items from the first table will be returned even if there is no matching item value in the second table.
The STRING_AGG aggregation function concatenates the values in the group together using the second argument as the delimiter - in this case a comma.
select
A.[G.R.N],
A.ITEM,
A.QUANTITY,
STRING_AGG(B.DELIVERY, ',') as DELIVERY,
SUM(B.QUANTITY) as DELIVERY_QUANTITY,
A.QUANTITY - SUM(B.QUANTITY) as QUANTITY_DIFFERENCE
from A
left join B on A.ITEM = B.ITEM
group by A.ITEM
Related
I just want to get the result which displays the reference which is not tallied in sum of table2. when i run my query below it will give me an wrong sum which it gets doubled even if group by cusid ,refno.
Table 1
RefNo
CusID
TotalAmount
1
1001
50
2
1001
30
3
1002
40
Table 2
RefNo
CusID
Particular
Amount
1
1001
Paper
30
1
1001
Pencil
30
2
1001
Ball
15
2
1001
Rubber
20
3
1002
Laptop
50
select * from Table1 a
INNER JOIN (Select CusID,RefNo, SUM(Amount) as CorrectTotal from Table2 group by
CusID,RefNo,
)b
ON b.CusID= a.CusID AND b.RefNo= a.RefNo
where a.TotalAmount != CorrectTotal
Expected Result
If you do it with FULL JOIN and with GROUP BY, you will also get rows where there is no record in the other table.
SELECT COALESCE(a.RefNo, b.RefNo) AS RefNo
, COALESCE(a.CusID, b.CusID) AS CusID
, a.TotalAmount
, SUM(b.Amount) AS CorrectTotal
FROM table1 a
FULL JOIN table2 b ON a.RefNo = b.RefNo
AND a.CusID = b.CusID
GROUP BY COALESCE(a.RefNo, b.RefNo)
, COALESCE(a.CusID, b.CusID)
, a.TotalAmount
ORDER BY 1, 2
Output
RefNo
CusID
TotalAmount
CorrectTotal
1
1001
50
60
2
1001
30
35
3
1002
40
50
8
888
88
(null)
9
999
(null)
99
See running demo on SQL Fiddle.
The other answer will work, but if you don't want to mess with a GROUP BY on the whole query you can also use an APPLY to do this:
SELECT a.*, c.CorrectAmount
FROM Table1 a
OUTER APPLY (
SELECT SUM(Amount) AS CorrectAmount
FROM Table2 b
WHERE b.CusID = a.CusID AND b.RefNo = a.RefNo
) c
WHERE a.TotalAmount <> c.CorrectAmount
**Table A :** **Table B:**
ITEMCODE Total QTY ITEMCODE Qty
A 100 A 25
B 50 A 75
C 75 B 10
D 85 B 20
B 30
D 80
D 5
Need to result view :
A 100 = A 25
A 75
How to get this result with SQL function with these two tables
If I understand correctly, you want the rows where the sum for the itemcode in b matches a. One method uses window functions:
select b.*
from (select b.*, sum(qty) over (partition by itemcode) as sumqty
from b
) b join
a
on a.itemcode = b.itemcode and a.qty = b.sumqty;
I have a dataset that I want to sum the values for by category (item), however before I sum them together I need to convert the currency of some values dependent on the currency in another column.
Sample dataset:
Item Currency Value
1 USD 10
1 PHP 100
2 USD 50
2 PHP 1000
3 PHP 500
select ITEM,
(case when CURRENCY='usd' then sum(VALUE*2) else sum(VALUE) end ) VALUE
from TABLE1
inner join TABLE2 on TABLE1.ID=TABLE2.ID
inner join TABLE3 on TABLE3.X=TABLE1.X
inner join TABLE4 on TABLE1.Y=TABLE4.Y
where A=1 and B=2 and C=5
group by ITEM, CURRENCY
ORDER BY ITEM asc
Desired outcome (using x2 as a factor to go from USD to PHP):
Item Value
1 120
2 1100
3 500
However, I am getting the following, which has correctly converted the currency, but is not grouping by item (ie. i'm getting duplicated rows for item rather than 1 row with the summed value):
Item Value
1 20
1 100
2 100
2 1000
3 500
The case should be the argument to the SUM():
select ITEM,
sum(case when CURRENCY='usd' then VALUE*2 else VALUE
end ) as VALUE
from TABLE1 join
TABLE2
on TABLE1.ID = TABLE2.ID join
TABLE3
on TABLE3.X = TABLE1.X join
TABLE4
on TABLE1.Y = TABLE4.Y
where A = 1 and B = 2 and C = 5
group by ITEM
ORDER BY ITEM asc;
Note: The GROUP BY is only by ITEM, because that defines the rows you want in the result set.
I have the following query,
SELECT * FROM Products P
OUTER APPLY
(
SELECT COALESCE(CP.NewPrice, CP.Price, 2147483647) AS MinimumChildPrice
--,SelectedMinimumPriceRow.Promotion
FROM Products CP
WHERE CP.ParentID = P.ID
) AS C
The problem is SelectedMinimumPriceRow.Promotion. I need to select this extra Promotion column of selected Minimum Price/NewPrice?
For example if I have,
ID ParentID Promotion Price NewPrice
----------------------------------------
1 NULL a 81 52
2 1 b 11 81
3 1 c 91 14
4 1 d 11 25
5 1 e 10 61
For ID=1, the minimum price will be 14. So, I need to select c as well.
You could simply replace your OUTER APPLY query with a TOP 1 query ordering by price, that will allow you to grab any column;
SELECT * FROM Products P
OUTER APPLY
(
SELECT TOP 1 COALESCE(CP.NewPrice, CP.Price, 2147483647) MinimumChildPrice,
promotion MinimumChildPricePromotion
FROM Products CP
WHERE CP.ParentID = P.ID
ORDER BY COALESCE(CP.NewPrice, CP.Price, 2147483647)
) AS C
An SQLfiddle to test with.
I have two Tables
Let suppose A and B
Now suppose the structure of table A is Like that
id stock
37 1
40 1
37 1
40 1
37 1
37 1
And B is like that
id stock
37 1
37 1
40 1
Now i want to write a query that give me sum of specific id stock in (table A - Table B) and if that id does not exist in table B then only stock from A.
So i will expect result like that
id stock
40 1
37 2
I thought that left join will be possible option here and i write query like that
SELECT A.id,
SUM(CAST(isNull(A.Stock, 0) as int) - CAST(isNull(B.Stock, 0) as int) )'Stock'
from A
LEFT OUTER JOIN
B
ON A.id = B.id
group by A.id
But Problem is that the above query gives desired records but wrong quantity/Stocklevel as shown below:
id stock
37 0
40 1
How can I resolve Stock Level issue.
I guess you are looking for something like this.
select A.id, A.SumA - coalesce(B.SumB, 0) as stock
from (
select A.id, sum(A.stock) as SumA
from A
group by A.id
) as A
left outer join
(
select B.id, sum(B.stock) as SumB
from B
group by B.id
) as B
on A.id = B.id
Result:
id stock
----------- -----------
37 2
40 1
SE Data
SELECT A.id, A.Stock - isNull(B.stock, 0) as Stock from A
LEFT OUTER JOIN B
ON A.id = B.id
That would be it I think.
PS. you group by something that you did not include in your case scenario. Your expected result is also not understandable to me (it conflicts with your problem description)