I have a query from my products and factors and factor items for show them.
In this query I'm showing a report from factor for user.
My query is :
WITH CTE AS
(
SELECT
ROW_NUMBER() OVER (ORDER BY FactoriTems.datesave ASC) AS rn,
FactoriTems.code, FactoriTems.replacement,
FactoriTems.suggcode, Factors.dateexport,
Productions.descriptions,
FactoriTems.countt, FactoriTems.price,
FactoriTems.countt * FactoriTems.price AS 'total',
Productions.country
FROM
Productions
INNER JOIN
FactoriTems ON Productions.code = FactoriTems.code
INNER JOIN
Factors ON Factors.gid = FactoriTems.gid
WHERE
(FactoriTems.gid = #gid)
)
SELECT *
FROM CTE
ORDER BY rn
This query is OK, but there is a problem, in Productions table some category have two or three product with one code, and when this codes are in factoritems table show two rows in my result set!
Result is :
rn
code
dateexport
descriptions
countt
price
total
1
aaa
12/24/2021
...
100
2
200
2
bbb
12/24/2021
...
200
3
600
3
ccc
12/24/2021
...
100
2
200
4
ddd
12/24/2021
...
200
3
600
5
ddd
12/24/2021
...
100
2
200
6
eee
12/24/2021
...
200
3
600
Now how can I show only one row for 'ddd' product code?
I tried to use DISTINCT but I got an error.
I want the output to be as follows:
rn
code
dateexport
descriptions
countt
price
total
1
aaa
12/24/2021
...
100
2
200
2
bbb
12/24/2021
...
200
3
600
3
ccc
12/24/2021
...
100
2
200
4
ddd
12/24/2021
...
200
3
600
5
eee
12/24/2021
...
200
3
600
Thanks
Just missing PARTITIN BY clause for the code column within the inner query. Rewrite your current query such as
WITH CTE AS
(SELECT ROW_NUMBER() OVER (PARTITION BY ft.code ORDER BY ft.datesave) AS rn0,
ft.code,
ft.replacement,
ft.suggcode,
f.dateexport,
p.descriptions,
ft.countt,
ft.price,
ft.countt * ft.price AS total,
p.country
FROM Productions p
JOIN FactoriTems ft
ON p.code = ft.code
JOIN Factors f
ON f.gid = ft.gid
WHERE (ft.gid = #gid))
SELECT ROW_NUMBER() OVER (ORDER BY datesave,code) AS rn,
code, replacement, suggcode, dateexport, descriptions,
countt, price, total, country
FROM CTE
WHERE rn0 = 1
ORDER BY rn
in order to filter out the duplicates for each distinct grouped code
Try this code:
WITH CTE AS
(SELECT ROW_Number() over (PARTITION BY FactoriTems.code ORDER by FactoriTems.datesave ASC) as rn,FactoriTems.code,
FactoriTems.replacement, FactoriTems.suggcode,Factors.dateexport,
Productions.descriptions, FactoriTems.countt, FactoriTems.price,
FactoriTems.countt * FactoriTems.price AS 'total', Productions.country
FROM Productions
INNER JOIN FactoriTems ON Productions.code = FactoriTems.code
INNER JOIN Factors ON Factors.gid = FactoriTems.gid
WHERE (FactoriTems.gid = #gid))
SELECT * FROM CTE
WHERE CTE.rn = 1
ORDER BY rn
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
I'm trying to reduce storage with packages included in sold products.
Products can have different amounts of same packages and invoice can have different amounts of products in separate lines. Action should be performed against certain invoiceID.
Simplified tables (summary is not column, just added to ease up calculation):
Inv_rows
InvID ProdID Qty *Summary*
999 100 2 *100 = 10*
999 101 2 *101 = 2*
999 102 2 *102 = 2*
999 103 2 *103 = 10*
999 100 8
999 103 8
Pack_to_prod
ProdID PackID Qty
100 A 2 *A = 20*
100 B 1 *B = 10*
101 A 1 *A = 2*
101 B 1 *B = 2*
102 A 3 *A = 6*
103 B 2 *B = 20*
Storage
ItemID Qty
A 100 *A = 28*
B 100 *B = 32*
**Desired Result**
Storage
ItemID Qty
A 72 *(100-28)*
B 68 *(100-32)*
What I have tried is:
UPDATE Storage
SET Storage.Qty = Storage.Qty -
(SELECT SUM (Inv_rows.Qty * Pack_to_prod.Qty) FROM Inv_rows
WHERE Inv_rows.ProdID IN (SELECT ProdID FROM Pack_to_prod
WHERE Pack_to_prod.PackID=Storage.ItemID) AND Inv_rows.InvId = 999
)
FROM Inv_rows, Storage, Pack_to_prod
WHERE Inv_rows.ProdID = Pack_to_prod.ProdID
AND Pack_to_prod.PackID = Storage.ItemID
AND Inv_rows.InvID = 999
But the problem is the 'IN' since it doesn't match the rows but I can't use '=' as 'where' results more than one line.
Then I tried to simplify it for myself (as I'm not a professional) with a select clause to understand what exactly needs to be done..
SELECT
Pack_to_prod.PackID AS PackageID,
Inv_rows.ProdID AS ProductID,
Inv_rows.Qty AS ProductQty,
Pack_to_prod.Qty AS PackageQtyPerProduct,
Inv_rows.Qty*Pack_to_prod.Qty AS PackageTotal,
Storage.Qty AS StorageQty,
Storage.Qty - (Inv_rows.Qty * Pack_to_prod.Qty) AS NewStorageQty
FROM Pack_to_prod,Inv_rows,Storage
WHERE Inv_rows.ProdID = Pack_to_prod.ProdID
AND Pack_to_prod.PackID = Storage.ItemID
AND Inv_rows.InvID = 999
GROUP BY Inv_rows.ProdID, Pack_to_prod.PackID, Pack_to_prod.Qty, Storage.Qty, Inv_rows.Qty
Which results as simple list showing the problem why they can't be just summed up:
PackageID ProductID ProductQty PackageQtyPerProduct PackageTotal StorageQty NewStorageQty
A 100 2 2 4 100 96
A 100 8 2 16 100 84
B 100 2 1 2 100 98
B 100 8 1 8 100 92
A 101 2 1 2 100 98
B 101 2 1 2 100 98
A 102 2 3 6 100 94
B 103 2 2 4 100 96
B 103 8 2 16 100 84
But can't figure out how to make it run 'line by line' so that each 'Pack_to_prod.Qty' would be handled separately.
Any help in right direction appreciated.
This seems like some aggregations and joins. To get the changes in values, then:
select pp.packid, sum(p.qty * pp.qty) as new_qty
from (select ir.prodid, sum(qty) as qty
from inv_rows ir
group by ir.prodid
) p join
Pack_to_prod pp
on pp.prodid = p.prodid
group by pp.packid;
You can then use this in an update:
update s
set s.qty = s.qty - pp.new_qty
from storage s join
(select pp.packid, sum(p.qty * pp.qty) as new_qty
from (select ir.prodid, sum(qty) as qty
from inv_rows ir
group by ir.prodid
) p join
Pack_to_prod pp
on pp.prodid = p.prodid
group by pp.packid
) pp
on pp.packid = s.itemid;
This was explained very well. The SQL code is user older coding conventions (such as JOIN conditions in the WHERE clause, instead of FROM) and isn't organized into subqueries properly. All the pieces are present though. I think something like this is what you're looking for.
with
inv_cte(ProdID, sum_qty) as (
select ProdID, sum(Qty)
from Inv_rows
group by ProdID),
pack_cte(PackID, prod_qty) as (
select pp.PackID, sum(pp.Qty*ic.sum_qty)
from Pack_to_prod pp
join inv_cte ic on pp.ProdID=ic.ProdID
group by pp.PackID)
select s.ItemID, s.Qty-p.prod_qty as ResultQty
from Storage s
join pack_cte p on s.ItemID=p.PackID;
Update statement
with
inv_cte(ProdID, sum_qty) as (
select ProdID, sum(Qty)
from Inv_rows
group by ProdID),
pack_cte(PackID, prod_qty) as (
select pp.PackID, sum(pp.Qty*ic.sum_qty)
from Pack_to_prod pp
join inv_cte ic on pp.ProdID=ic.ProdID
group by pp.PackID)
update s
set Qty=Qty-p.prod_qty
from Storage s
join pack_cte p on s.ItemID=p.PackID;
I Have 3 tables Customer, Bank and BankTransaction.
On My View I want to display each customer with their Balance in the bank account.
Here is my tables
Customer
Id Name
---------
1 John
2 Jack
Bank
Id CustomerId BankName
----------------------------------
1 1 HSBC
2 2 HSBC
BankTransaction
Id BankID MoneyIn MoneyOut Balance
---------------------------------------------
1 1 1000 0 1000
2 1 0 500 500
3 2 2000 0 2000
4 2 2000 0 4000
5 2 1000 0 5000
Now I want to Display following data view query
John 500
Jack 5000
Last Balance of each customer
Try this
SELECT A.Name,
Sum(C.MoneyIN) - Sum(C.MoneyOut) AS Balance
FROM #Customer A
JOIN #Bank B ON A.Id = B.id
JOIN #BankTransaction C ON B.Id = C.BankID
GROUP BY A.Name
Using Window function you can get the result. Try this.
;WITH cte
AS (SELECT Row_number() OVER (partition BY b.id ORDER BY a.id DESC) rn,
c.Name,
a.balance
FROM BankTransaction a
JOIN bank b ON a.BankID = b.Id
JOIN Customer c ON c.Id = b.CustomerId)
SELECT name, balance
FROM cte
WHERE rn = 1
I'm working on a problem which is something like this :
I have a table with many columns but major are DepartmentId and EmployeeIds
Employee Ids Department Ids
------------------------------
A 1
B 1
C 1
D 1
AA 2
BB 2
CC 2
A1 3
B1 3
C1 3
D1 3
I want to write a SQL query such that I take out 2 sample EmployeeIds for each DepartmentID.
like
Employee Id Dept Ids
B 1
C 1
AA 2
CC 2
D1 3
A1 3
Currently I am writing the query,
select
EmployeeId, DeptIds, count(*)
from
table_name
group by 1,2
sample 2
but it gives me total two rows.
Any help?
If the number of departments i know and small you could do a stratified sampling:
select *
from table_name
sample
when DeptIds = 1 then 2
when DeptIds = 2 then 2
when DeptIds = 3 then 2
end
Otherwise a combination of RANDOM and ROW_NUMBER:
select *
from
(
sel EmployeeId, DeptIds, random(1,10000000) as rand
from table_name
) as dt
qualify
row_number()
over (partition by DeptIds
order by rand) <= 2
I have a table with self referencing relation,
ID parentID UserId Title
1 null 100 A
2 1 100 B
3 2 100 C
4 2 100 D
5 null 100 E
6 5 100 F
I want to update UserId from 100 to 101 for all records with ID=1 and its children, so I want to have
ID parentID UserId Title
1 null 101 A
2 1 101 B
3 2 101 C
4 2 101 D
5 null 100 E
6 5 100 F
How can I do it in T-SQL?
You probably want to use a common table expression which allows you to generate recursive queries.
eg:
;with cte as
(
select * from yourtable where id=1
union all
select t.* from cte
inner join yourtable t on cte.id = t.parentid
)
update yourtable
set userid = 101
where id in (select id from cte)