Select query where column does not equal column in different table in SQL Server - sql

I have two different tables that contain order/pricing data. The first table, Orders, has columns order, item and price. The second table, Pricing has columns item, price, and effective date. I want to find all orders where orders.price <> pricing.price where effective date = 7/27/2017.
Orders:
Order Item Price
---------------------
1 ABC 12.50
2 ABC 12.00
3 ABC 11.50
4 XYZ 20.00
Pricing:
Item Price Effective Date
-------------------------------
ABC 12.50 7/27/2017
ABC 12.00 12/1/2016
ABC 11.50 12/1/2015
XYZ 25.00 7/27/2017
XYZ 20.00 12/1/2016
I want the query to tell me that order 2,3,4 do not have the most up to date pricing.
Please advise.

SELECT O.ORDER, (P.PRICE - O.PRICE) AS 'Variance'
FROM ORDERS O, PRICING P
WHERE O.ITEM = P.ITEM
AND P.[EFFECTIVE DATE] = '7/27/2017'
AND P.PRICE <> O.PRICE
ORDER BY O.ORDER ASC

It should be like this:-
SELECT * FROM Orders O
INNER JOIN Pricing P ON O.Item = P.Item
Where O.Price != P.Price AND [Effective Date] ='07/27/2017'

Are you looking for something like this?
SELECT o.[Order]
FROM Orders o JOIN Pricing p
ON o.Item = p.Item
AND p.Effective_Date = '2017-07-27'
AND o.price <> p.price
SQLFiddle demo
Output:
| Order |
|-------|
| 2 |
| 3 |
| 4 |

select o.order,o.Item,o.price from orders o inner join
pricing on o.item=pricing.item
where o.price <>(select p.price from pricing p where p.effectivedate = '2017-07-27' and p.item=o.item)

Related

SQL Query to get value of recent order alongwith data from other tables

I am writing an SQL query to get data from more than 3 tables, but for simplifying the question here I am using a similar scenario with 3 tables.
Table1 Customer (PK-CustomerID, Name)
CustomerID
Name
1
John
2
Tina
3
Sam
Table2 Sales (FK-Id, SalePrice)
ID
SalePrice
1
200.00
2
300.00
3
400.00
Table3 Order (PK-Id, FK-CustomerID, Date, Amount)
Id
CustomerID
Date
Amount
101
1
25-09-2021
30.0
102
1
27-09-2021
40.0
103
2
19-09-2021
60.0
In the output, Date and Amount should be the from most recent Order (latest Date), for a customer
My approach was
Select c.CustomerID, c.Name, s.SalePrice, RecentOrder.Date, RecentOrder.Amount from
Customer as c
LEFT JOIN Sales s ON c.CustomerID = s.ID
LEFT JOIN (SELECT top 1 o.Date, o.Amount, o.CustomerID
FROM Order o, Customer c1 WHERE c1.CustomerID = o.CustomerID ORDER BY o.Date DESC)
RecentOrder ON c.CustomerID = RecentOrder.CustomerID
Output I get
CustomerID, Name, SalePrice, Date, Amount
CustomerID
Name
SalePrice
Date
Amount
1
John
200.00
27-09-2021
40.0
2
Tina
300.00
null
null
3
Sam
400.00
null
null
The output I get includes the most recent order out of all the orders. But I want to get the recent order out of the orders made by that customer
Output Required
CustomerID, Name, SalePrice, Date, Amount
CustomerID
Name
SalePrice
Date
Amount
1
John
200.00
27-09-2021
40.0
2
Tina
300.00
19-09-2021
60.0
3
Sam
400.00
null
null
Instead of subquery in left join, you can check with outer apply.
Check following way
Select c.CustomerID, c.Name, s.SalePrice, RecentOrder.Date, RecentOrder.Amount
from Customer c
LEFT JOIN Sales s ON c.CustomerID = s.ID
OUTER APPLY (
SELECT top 1 o.Date, o.Amount, o.CustomerID
FROM [Order] o
WHERE o.CustomerID = c.CustomerID ORDER BY o.Date DESC) RecentOrder`
You need to pre-aggregate or identify the most recent order for each customer order, your query is selecting 1 row for all orders.
Try the following (untested!)
select c.CustomerID, c.Name, s.SalePrice, o.Date, o.Amount
from Customer c
left join Sales s on c.CustomerID = s.ID
outer apply (
select top (1) date, amount
from [order] o
where o.CustomerId=c.CustomerId
order by Id desc
)o

How to retrieve unpaid amount of each invoice for finance charges?

I am working on implementing finance charges, but don't know how to retrieve the unpaid amount of each invoice. I am not new to SQL, however this problem has me stumped. Forgive me if I just didn't search properly.
So, let us say I have an invoice table:
id | amount
----+--------------
1 | 50.00
2 | 50.00
3 | 50.00
4 | 50.00
5 | 50.00
And a payments table:
amount
--------------
50.00
25.00
The result set should be this:
invoice_id | unpaid_amount
------------+--------------
2 | 25.00
3 | 50.00
4 | 50.00
5 | 50.00
Of course, there is quite a bit more to add to implement finance charges, but I think I can get the rest.
Edit: Sorry, an oversight of mine. The id's are not related. Removed payment id column.
Edit 2: These are fictual numbers, the real life numbers will be anything, so no matches can be made on the amounts.
Edit 3: And here I have created a SQL Fiddle to show what I have so far, based on #GordonLinoff second answer. I would appreciate a cleaner approach than the kludgy SQL I concocted.
I think you want a join:
select i.id as invoice_id,
(i.amount - coalesce(p.amount, 0)) as net_amount
from invoice i left join
payment p
on i.id = p.id;
EDIT:
Or, you may want:
select i.*,
(case when sum(i.amount) over (order by i.id) < p.amount
then i.amount
else greatest(p.amount - sum(i.amount) over (order by i.id) + i.amount, 0)
end) as amount_paid
from invoice i cross join
(select sum(amount) as amount
from payment
) p;
Here is a db<>fiddle.
You can do by using LEFT JOIN and subtract amounts from both table. COALSECE is here to prevent you from getting NULL when there is no payment.
select
i.id as invoice_id
,i.amount - coalesce(p.amount,0) as amount
from invoice i
left join payments p
on p.id = i.id
If in your payments talbe can be more than one payment for an invoice you should group payments before joining it to invoice.
select
i.id as invoice_id
,i.amount - coalesce(p.amount,0) as amount
from invoice i
left join (select id, sum(amount) as amount from payments group by id) p
on p.id = i.id

Query to pull previous order date corresponding to a customer?

I have a schema with Customer table and Order table. A customer can place order in multiple dates. I need to have previous order_date for every order_date corresponding to a customer.
Say a customer placed 4 orders, then for newest order(4th order) - it must pull current order_date and previous order_date(3rd order). For 3rd order placed by customer, it must pull 3rd order_date as current order_date and previous order_date(2nd order) as so on.
I am using below query to get previous order_date and then joining with current_query to get result::
select customerid, orderid, order_date as previous_order_date
from (
select c.customerid, o.orderid, o.order_date,
row_number() over (partition by c.customerid, o.orderid
order by o.order_date) rown
from customers c join orders o on c.customerid = o.customerid
) a
where rown = 2
But the issue is, I am getting a single date corresponding to a customerid whereas the requirement is - just previous order_date corresponding to current order_date for a customer.
Any suggestion would help! Thanks
Try with LAG() window function per customerid:
select
c.customerid, o.orderid, o.order_date,
lag(o.order_date) over (partition by c.customerid order by o.order_date) AS prev_order_date
from customers c
join orders o on c.customerid = o.customerid
For the earliest order of every customer prev_order_date will be null.
Sample result (don't mind orderid, it's just for the example):
customerid | orderid | order_date | prev_order_date
------------+---------+------------+-----------------
1 | 6 | 2015-02-08 |
1 | 2 | 2016-02-05 | 2015-02-08
1 | 3 | 2016-02-08 | 2016-02-05
1 | 1 | 2016-03-05 | 2016-02-08
2 | 5 | 2016-07-01 |
2 | 4 | 2016-07-08 | 2016-07-01
If one customer can place the same order within different dates (weird, but this seems to be your case) add o.orderid to the PARTITION BY clause.
Unfortunately, LAG() didn't work when used in SQL node for reporting purpose. I tried using below query and got desired result:
SELECT c.customer_code, o.customer_sid, o.order_id, o.order_no,
o.order_created_date,
(SELECT MAX (o1.order_created_date)
FROM d_customer c1 LEFT JOIN f_order o1
ON c1.customer_sid =
o1.customer_sid
WHERE c1.customer_sid = c.customer_sid
AND o1.order_created_date < o.order_created_date
AND EXISTS (SELECT 1
FROM f_invoice i
WHERE i.order_id = o1.order_id))
AS prev_order_created_date,
t.financial_year, t.financial_month_no
FROM d_customer c JOIN f_order o
ON c.customer_sid = o.customer_sid
AND c.customer_type = 'PATIENT'
AND c.customer_country = 'UNITED STATES'
AND o.customer_type = 'PATIENT'
AND o.bill_to_country = 'UNITED STATES'
AND o.order_status = 'SHIPPED'
AND o.order_type = 'SALES'
AND o.order_group = 'REVENUE'
-- AND c.customer_code = '233379PT'
LEFT JOIN d_time t ON t.time_sid = o.order_created_date_sid
ORDER BY order_created_date DESC

stock query not show exact result

I use this query to maintain my stock but its not show exact result
select p.Product_Name Product
,isnull(sum(d.qty),0) Purchase_Qty
,isnull(sum(i.qty),0) Issue_Qty
,(isnull(sum(d.qty),0)-isnull(sum(i.qty),0)) InStock
from purchase_dtl d
left join issue_dpt i on i.Product_ID=d.Product_ID
right join product p on p.id = d.Product_ID
group by Product_Name
Query result
Product | Purchase_Qty | Issue_Qty | InStock
---------------------------------------------
Pen 1000 300 700
Books 4000 1000 3000
My exact purchase qty
Product | Purchase_Qty
----------------------
Pen 500
Books 2000
My exact issue qty
Product | Issue_Qty
-------------------
Pen 300
Books 1000
Please help me to solve my problem
Thanks
select p.Product_Name Product
, p.Purchase_Qty
, isnull(sum(i.qty),0) Issue_Qty
, p.Purchase_Qty-isnull(sum(i.qty),0) InStock
from (select p.id, p.Product_Name, isnull(sum(d.qty),0) Purchase_Qty
from product p left join purchase_dtl d on p.id = d.Product_ID
group by p.id, p.Product_Name) p
left join issue_dpt i on i.Product_ID = p.id
group by Product_Name, p.Purchase_Qty
I suppose joining purchase_dtl and issue_dpt gives you some extra rows for Purchase_Qty
Join product with purchase_dtl first to calculate the aggregate data and then join again with issue_dpt

MS-Access Get price of product at certain order date

I have a table filled with purchase prices, like this:
sku price btw startdate
PCR-CA5425023181515 21,17 € 1 01/01/2009
PCR-CA5425023181515 999,00 € 1 06/06/2009
PCR-CA5425023181515 444,00 € 4 09/07/2009
PCR-CA5425023181515 100,00 € 4 10/08/2009
I have another table filled with orders, like this:
sku quantity orderdate
PCR-CA5425023181515 5 01/05/2009
PCR-CA5425023181515 10 01/12/2009
PCR-CA5425023181515 10 24/12/2009
My goal is to get every purchase price per order from that date.
(For example: when I ordered the product on the first of may (01/05) it cost 21,17 euros.
When I ordered it on the first of december (01/12) it cost 100,00 euros.)
I've been struggling with this for the past hour, but haven't found anything useful yet.
SELECT
O.sku,
O.qty,
PP.price
FROM
Orders O
INNER JOIN Purchase_Prices PP ON
PP.sku = O.sku AND
PP.start_date <= O.order_date
WHERE
NOT EXISTS
(
SELECT
*
FROM
Purchase_Prices PP2
WHERE
PP2.sku = PP.sku AND
PP2.start_date <= O.order_date AND
PP2.start_date > PP.start_date
)
Alternatively:
SELECT
O.sku,
O.qty,
PP.price
FROM
Orders O
INNER JOIN Purchase_Prices PP ON
PP.sku = O.sku AND
PP.start_date <= O.order_date
LEFT OUTER JOIN Purchase_Prices PP2 ON
PP2.sku = O.sku AND
PP2.start_date <= O.order_date AND
PP2.start_date > PP.start_date
WHERE
PP2.sku IS NULL