Remove duplicated results using inner join? - sql

I want to see TotalSale values ONLY on the first row of TotalSale that matches with PricesTable DocNumber and DocType
SalesTable
ProductID DocType DocNumber UnitPrice
01 A 000001 150.00
05 A 000001 200.00
06 A 000001 80.00
65 C 002550 15000.00
30 B 002551 100.00
and
PricesTable
DocType DocNumber TotalSale
A 000001 430.00
C 002550 15000.00
B 002551 100.00
What I want to get is something like this
TotalSalesTable
ProductID DocType DocNumber UnitPrice TotalSale
01 A 000001 150.00 430.00
05 A 000001 200.00
06 A 000001 80.00
65 C 002550 15000.00 15000.00
30 B 002551 100.00 100.00
but instead I keep getting this:
TotalSalesTable
ProductID DocType DocNumber UnitPrice TotalSale
01 A 000001 150.00 430.00--> Good Value
05 A 000001 200.00 430.00--> This
06 A 000001 80.00 430.00--> and this are duplicated
65 C 002550 15000.00 15000.00
30 B 002551 100.00 100.00
This is the query I'm using:
SELECT ST.ProductID
,ST.DocType
,ST.DocNumber
,ST.UnitPrice
,PT.TotalSale
from SalesTable ST
INNER JOIN PricesTable PT
on (ST.DocNumber=PT.DocNumber)

I think you can try enumerating all the rows, then assign totalsales value only to those rows that are first for every docnumber:
SELECT ST.ProductID
,ST.DocType
,ST.DocNumber
,ST.UnitPrice
,case when row_number() over
(partition by st.docnumber order by st.productid) = 1
then PT.TotalSale end as TotalSale
from SalesTable ST
INNER JOIN PricesTable PT
on (ST.DocNumber=PT.DocNumber)
Edit: I would also recommend having two columns: one with a duplicated values for every docnumber, and another one with those values hidden except the first one. So that in future you can calculate ratios and aggregates from the output more comfortably.

You can get the required results without the need of the second table (PricesTable),
Select ProductID, DocType, DocNumber, UnitPrice,
Case When ROW_NUMBER() Over (Partition By DocType, DocNumber Order By ProductID) = 1
Then SUM(UnitPrice) Over (Partition By DocType, DocNumber)
Else ''
End as TotalSale
From SalesTable
See a demo from db<>fiddle.

Related

Discount Present Update When Quantity Change

I have table call tblInvoice. This is my table with some data.
InvoiceNo
ItemName
Quantity
CostPrice
ItemCode
DiscountPrice
DisPresent
Amount
GrossAmount
SalePrice
INV01
80= BK
10
30.00
EX80=
40.00
100.00
400.00
575.00
50.00
INV01
80= BK
5
30.00
EX80=
35.00
75.00
175.00
575.00
50.00
My client is sell same item with different price. as you can see here DiscountPrice is different but ItemName and ItemCode is same. When return product after sold I want to subtraction quantity. Its ok I already done that part. But problem is I want to update DiscountPesent after return product. its like this. Imagine I return 1 Book DiscountPrice is 40.00. Not 35.00. I want to update only first row. not both rows. I want to get DiscountPresent Like this.
SalePrice - DiscountPrice * Quantity = DiscountPresent
According to the above table. Imagine I subtraction 1 Quantity from DiscountPrice 40.00 row. now My Quantity is 9 I want to get DiscountPresent Like this.
50 - 40 = 10 * 9 = 90
I used following query for achieve this. sometimes its work as expected. but sometimes DiscoutPresent Switching with second row DiscountPeresent. After that table look like this.
InvoiceNo
ItemName
Quantity
CostPrice
ItemCode
DiscountPrice
DisPresent
Amount
GrossAmount
SalePrice
INV01
80= BK
9
30.00
EX80=
40.00
75.00
400.00
575.00
50.00
INV01
80= BK
5
30.00
EX80=
35.00
90.00
175.00
575.00
50.00
90 is come to second row. 75 is come to first row. its wrong. I used following code. sometimes its work as expected. but sometimes it switching DiscountPresent.
UPDATE ps
SET DisPresent = ((i.SalePrice) - (i.DiscountPrice)) * (i.Quantity)
FROM tblInvoice ps JOIN
(SELECT i.InvoiceNo, i.DiscountPrice, i.Quantity, i.SalePrice FROM tblInvoice i
GROUP BY i.DiscountPrice, i.InvoiceNo, i.Quantity, i.SalePrice)i
ON ps.InvoiceNo = i.InvoiceNo
looks to me you only need a simple update statement
UPDATE i
SET DisPresent = (i.SalePrice - i.DiscountPrice) * i.Quantity
FROM tblInvoice i
if this is not what you wanted, please show the expected result for the sample data that you have provided
if you are returning any product you should update only that invoice
UPDATE ps
SET DisPresent = ((i.SalePrice) - (i.DiscountPrice)) * (i.Quantity)
FROM tblInvoice where invoiceid=1 and itemcode='EX80='

Get SUM of Reference table rows

tblOrders
OrderId totalamount OrderStatus
01 1000 4
02 2000 4
tblCart
CartId OrderId NetPrice
05 01 400
06 01 650
07 02 750
08 02 1350
Desired Result:
OrderId totalamount OrderStatus NetPrice ItemCount
01 1000 4 1050 2
02 2000 4 2100 2
I want to achieve the JOIN of two tables with SUM(Netprice) based on OrderId Link
I tried doing this using SQL Query for a Stored Procedure but its giving ambiguous column error.
Please use below query,
select t1.OrderId, t1.totalamount, tl1.OrderStatus, sum(t2.NetPrice) as NetPrice ,
count(1) as ItemCount from
tblOrders t1
inner join tblCart t2
on (t1.OrderId = t2.OrderId)
group by t1.OrderId, t1.totalamount, tl1.OrderStatus;
If you want all columns from the orders table and summarized data from the other, you might find that apply is helpful:
select o.*, c.*
from tblOrders o outer apply
(select sum(c.netprice) as netprice, count(*) as itemcount
from tblCart c
where c.OrderId = o.OrderId
) c;

Join on one date entry in one table being the closest date to another entry in another table

I am trying to basically reconcile two separate payment tables I have, one that bases the payments off when the payment was actually made, and the other that has the payment when it was actually processed. Some brain genius decided that it wouldn't be a great idea for both of these tables to have some unique ID that could join together so I've had to take the long way around. I imagine this involves joining both tables using a subquery but I have no idea how to write it. Here are the tables and I'll explain what I want to do a bit more afterwards
payment table
account_id payment_refID payment_date Amount
000001 AAA 01/01/2019 5.00
000001 BBB 03/01/2019 5.00
000001 CCC 05/01/2019 5.00
000001 DDD 31/01/2019 5.00
000001 EEE 02/02/2019 5.00
000001 FFF 28/02/2019 5.00
000001 GGG 05/03/2019 5.00
transaction table
account_id2 payment_refID payment_date Amount
000001 111 08/01/2019 5.00
000001 222 10/01/2019 5.00
000001 333 12/01/2019 5.00
000001 444 08/02/2019 5.00
000001 555 15/02/2019 5.00
000001 666 03/03/2019 5.00
000001 777 12/03/2019 5.00
here's how my code looks so far
SELECT *
from payments a
join trasnaction b
on a.account_id = b.account_id2
and a.amount = b.amount
and [b.transactiondate is the closest transaction date after a.transactiondate. This is what I need help with]
so basically when I join up the tables I would want it to look like this:
The join would basically be 1:1 in the example above with payment ref AAA matching up to 111 and BBB matching up to 222
I would not be able to just join on the dates being a week after since some payments may get processed quicker or slower and there might be multiple payments on the same day. Any help is appreciated
If you have not a relationship between payments.payment_refID and transactions.payment_refID you will have big troubles.
In your example AAA, BBB and CCC will all match 111 instead of 111, 222 and 333, so if you have not rules on how to join the tables.. simply you can't.
If the "distance" between payment and transaction is fixed (ie one week).. you can refine the search, but you will not be sure at 100% because you can get wrong results for payments made in the same day.
The only solution is to assume that payment_refID in both tables is in ascending order and that each transaction is related to its payment in cronological order.
So you can number all payments and all transactions and join them on that counter.
In Microsoft SQL Server you can try this:
;with
p as (
select *, ROW_NUMBER() over (partition by p.account_id order by p.payment_date, p.payment_refID) n
from payments p
),
t as (
select *, ROW_NUMBER() over (partition by t.account_id2 order by t.payment_date, t.payment_refID) n
from transactions t
)
select *
from p
join t on p.account_id = t.account_id2 and p.n = t.n

How to return preceding row value with column condition in SQL table?

I have the below SQL table in which I need the most recent price only when condition type is 00:
ProductID ConditionType Date Price
00001 01 2018-01-01 4.00
00001 01 2018-01-08 5.00
00001 00 2018-01-09 4.50
00001 01 2018-01-22 6.00
00001 00 2018-01-29 3.00
I have tried using a lag function but am having trouble with the partitions.
select
ProductID,ConditionType,Date,Price
,
case when conditiontype = 0 then
lag(Price,1) over (partition by ProductID,ConditionType order by Date asc)
else Price
end as lag
from TABLE
Output from query:
ProductID ConditionType Date Price Lag
00001 01 2018-01-01 4.00 4.00
00001 01 2018-01-08 5.00 5.00
00001 00 2018-01-09 4.50 null
00001 01 2018-01-22 6.00 6.00
00001 00 2018-01-29 3.00 4.50
Ideally we want to pull back the last price where condition type is 01 but I am having trouble getting this working.
Desired output:
ProductID ConditionType Date Price Lag
00001 01 2018-01-01 4.00 4.00
00001 01 2018-01-08 5.00 5.00
00001 00 2018-01-09 4.50 5.00
00001 01 2018-01-22 6.00 6.00
00001 00 2018-01-29 3.00 6.00
You can do this using first_value() and ignoring NULL values:
select t.*,
first_value(case when conditionType = '00' then price end ignore nulls) over
(partition by productId
order by date desc
) as most_recent_00_price
from t;
EDIT:
I misunderstood the question. I thought you wanted the most recent in the data. You want the "running" most recent value.
The simplest way in SQL uses lag(ignore nulls), but that is not supported by Impala. But you can use two window functions:
select t.*,
max(case when date = date_00 then price end) over (partition by productId) as most_recent_00_price
from (select t.*,
max(case when conditionType = '00' then date end) over (partition by productId order by date) as date_00
from t
) t
You only need one partition clause in lag() :
select ProductID, ConditionType, Date, Price,
(case when conditiontype = '00'
then lag(Price) over (partition by ProductID order by Date)
else Price
end) as Lag
from TABLE;

SQL Problem : Query

I have an issue in query. I have tables product, stockRecord and priceDetail. I want to display all products. If the price is not defined in priceDetail for that product, then it will be 0.00; similarly if the quantity is not defined in stockRecord table, then the quantity should be 0.
But if the price is defined in the priceDetail table, then we should get the latest price from the table
WMProduct
BusinessUnit ProductCode Description SalableFlag
MASS 0001 Pen 1
MASS 0002 Computer 1
MASS 0003 Book 1
MASS 0004 Bottle 1
WMStockRecord
ProductCode AvailableQuantity
0001 10
0003 15
WMPriceDetail
ProductCode DateFrom DateTo Price
0001 10-10-2009 10-10-2011 100
0001 10-12-2009 10-10-2010 80
0001 12-12-2010 01-12-2011 120
0002 12-01-2010 '' 200
0004 12-12-2010 12-05-2011 100
I need list of products like this:
BusinessUnit ProductCode Description SalableFlag Price AvailableQuantity
MASS 0001 Pen 1 120 10
MASS 0002 Computer 1 200 0
MASS 0003 Book 1 0.00 15
MASS 0004 Bottle 1 0.00 0
Try using sub query and left join like below :
SELECT P.ProductCode AS ProductCode,
P.Description AS ProductName,
P.SalableFlag AS Salable,
ISNULL(STK.AvailableQuantity, 0) AS Qty,
ISNULL((SELECT TOP 1 Price FROM WMPriceDetail
WHERE ProductCode = P.ProductCode ORDER BY DateTo DESC), 0) AS Price
FROM WMProduct P
LEFT JOIN WMStockRecord STK ON P.ProductCode = STK.ProductCode