sql join on join - sql

transactions table (1 row --> 1 transaction)
customer_code amount
A0BEFG 100
DEC21A 80
payment table (1 row --> 1 transaction)
customer_id payment_type
1 cash
2 credit_card
customer table (1 row --> 1 customer_code)
customer_code customer_id
A0BEFG 2
DEC21A 1
Expected output:
combined table
customer_code customer_id amount payment_type
AOBEFG 2 100 credit_card
DEC21A 1 80 cash
In words, my idea is to get the payment_type into the transactions table, but because there is no matching variable, I need to first merge payment table and customer table, before connecting them to the transactions table.
Code I've tried:
with
connection as (
select c.customer_code, c.customer_id, p. payment_type
from data.payment p
left join data.customer c on p.customer_id = c.customer_id
),
transactions as (
select t.merchant_code, t.amount
from data.transactions t
)
select
t.merchant_code, c.customer_id, c.amount, p.payment_type
from transactions as t
Code is for PostgreSQL.

SELECT c.customer_code, c.customer_id, t.amount, p.payment_type
FROM customer AS c
INNER JOIN payment AS p ON p.customer_id = c.customer_id
INNER JOIN transactions AS t ON t.customer_code = c.customer_code

Join customer to the other tables like this:
SELECT c.customer_code, c.customer_id, t.amount, p.payment_type
FROM transactions t
INNER JOIN customer c ON t.customer_code = c.customer_code
INNER JOIN payment p ON p.customer_id = c.customer_id
See the demo.
Results:
customer_code
customer_id
amount
payment_type
A0BEFG
2
100
credit_card
DEC21A
1
80
cash

Related

Add all Quantity Value with the same ID

I want to get the sum of Qty Column with the same ProductID.
Qty
ProductID
1
1001
1
1002
1
1002
1
1001
1
1001
1
1001
So far this is my query:
SELECT
Sales.Qty,
Sales.ProductID,
Products.ProductDesc,
Sales.Status FROM
dbo.Sales
INNER JOIN dbo.Products ON Sales.ProductID = Products.ProductID
Assuming that ProductID uniquely identifies a product, you could group by the ProductID and ProductName:
SELECT SUM(Sales.Qty),
Sales.ProductID,
Products.ProductDesc,
FROM dbo.Sales
INNER JOIN dbo.Products ON Sales.ProductID = Products.ProductID
GROUP BY Sales.ProductID, Products.ProductDesc

How to Sum previos rows summatory to find a balance in SQL Server

I'm working on a service that needs to calculate how much a customer owes, according to a total invoice value and the partial payments that the customer has made.
So, in a tableA I have a row with the invoice total value:
[dbo].[TableA]
ID CustomerId InvoiceVal
1 12 1000
2 11 2000
3 10 5000
4 14 15000
5 12 100
6 16 8000
7 18 3200
In a TableB I have the record of each customer's partial payments they have made to each invoice:
[dbo].[TableB]
ID InvoiceId Payment
1 1 150
2 3 50
3 1 120
4 1 100
5 5 90
6 4 7500
So, as you can see, the customer 12 has an invoice for $1000 and has made 3 payment that sum $370
I need to be able to se the partial total owed in each row, this is the expected result:
No. InoviceId CustomerId Payment Owed
1 1 12 150 850
2 1 12 120 730
3 1 12 100 630
So far, this is my code:
DECLARE #invid int = '1'
DECLARE #invoicetotal numeric(18,2)
SET #invoicetotal =
(
SELECT
[dbo].[TableA].[InvoiceVal]
FROM [dbo].[TableA]
WHERE
([dbo].[TableA].[ID] = #invid)
)
SELECT
*,
SUM(#invoicetotal - [dbo].[TableB].[Payment]) OVER(ORDER BY [dbo].[TableB].[ID] ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) AS [Owed]
FROM [dbo].[TableB]
WHERE
([dbo].[TableB].[InvoiceId] = #invid)
But this is what I get:
ID InvoiceId Payment Owed
1 1 150.00 NULL
3 1 120.00 850.00
4 1 100.00 1730.00
I need to sum the previous payment on each row.
Thanks!
Something like this would help
SELECT
ROW_NUMBER() OVER (ORDER BY TableB.ID ASC) NO,
CustomerId,
Payment,
InvoiceVal - SUM(Payment) OVER (PARTITION BY TableA.ID ORDER BY TableB.Id ASC) Owed
FROM TableA
INNER JOIN TableB
ON TableA.Id = TableB.InvoiceId
WHERE
CustomerId = 12
Working Fiddle
Your query will depend on what you are trying to make as your final output.
If you want just ONE CustomerID, go with:
SELECT a.ID AS InvoiceID, a.CustomerID, a.InvoiceVal AS StartInvoice
, b.ID AS bid, b.Payment
, a.InvoiceVal - ISNULL(SUM(b.Payment) OVER (PARTITION BY a.ID ORDER BY b.id),0) AS owed
FROM TableA a
LEFT OUTER JOIN TableB b ON a.ID = b.InvoiceID
WHERE a.CustomerID = 12
And if that CustomerID doesn't have any payments, you want to use a LEFT JOIN so that you don't eliminate an amount owed.
SELECT a.ID AS aid, a.CustomerID, a.InvoiceVal AS StartInvoice
, b.ID AS bid, b.Payment
, a.InvoiceVal - ISNULL(SUM(b.Payment) OVER (PARTITION BY a.ID ORDER BY b.id),0) AS owed
FROM TableA a
LEFT OUTER JOIN TableB b ON a.ID = b.InvoiceID
WHERE a.CustomerID = 11
I also added an ISNULL() around Payment to keep from nulling out your owed amount. It could also be added to the InvoiceVal to account for a CustomerID who hasn't been invoiced yet, if that was needed (or possible from other tables).
IF you want to get ALL CustomerIDs, you'll have to account for that in your partition.
SELECT s1.CustomerID, aid AS InvoiceID, s1.bid, s1.Payment
, (s1.StartInvoice - s1.runningPayment) AS Owed
FROM (
SELECT a.ID AS aid, a.CustomerID, a.InvoiceVal AS StartInvoice
, b.ID AS bid, b.Payment
, ISNULL(SUM(b.Payment) OVER (PARTITION BY a.CustomerID, a.ID ORDER BY b.id),0) AS runningPayment
FROM TableA a
LEFT OUTER JOIN TableB b ON a.ID = b.InvoiceID
) s1
ORDER BY s1.CustomerID, s1.aid, s1.bid
Fiddle demonstrates overpayment or paying total balance for 0 owed.

Group By / Having correlated subquery

I am trying to solve this query, I'm really lost
least one order in which the quantity they ordered was greater than
the average quantity of all other orders.
My tables are:
Customer
Cust_ID | CustName | Region | Phone
Orders
Ordernum | Cust_ID | Item_ID | Quantity
Vendor
Vendor_ID | Item_ID | Costs | Region
stock
Item_ID | Description | Price | On_hand
Database schema is:
Customer (Cust_ID, CustName, Region, Phone)
Orders (Ordernum, Cust_ID, Item_ID, Quantity) Foreign key Cust_ID
references Customer Not Null, On Delete Restrict
Foreign key Item_ID references Stock Not Null, On Delete Restrict
Stock (Item_ID, Description, Price, On_hand)
Vendor (Vendor_ID, Item_ID, Cost, Region)
Foreign key Item_ID references Stock Not null, On Delete Restrict
Here is what I have tried so far. What am I doing wrong?
select custname, phone, count(distinct(item_id)), sum(quantity)
from customer c, orders o
Where c.cust_id= o.cust_id and count (o.ordernum) >= 2
group by cust_id
having sum (quantity) >
(select avg(quantity)
from orders o2
where o.item_id != o2.item_id)
order by custname;
I re-wrote my code and this is what I came up with. I'm really lost:
select c1.custname, phone, count(distinct(o.item_id)), sum(quantity) as quantity
from customer c1, orders o
Where c1.cust_id= o.cust_id
group by c1.cust_id, custname, phone, quantity
Having 2>=
(select count(o1.item_id)
From orders o1
where c1.cust_ID = o1.cust_ID)
AND sum(quantity) >
(select AVG(quantity)
from orders o2
Where c1.cust_ID != o2.cust_ID AND o.Item_ID = o2.Item_ID)
order by custname;
Try this query
select a.cust_id, count(distinct Item_ID) as itemOrderd,
sum(b.quantity) as sum
from
customer a
inner join
orders b
on a.cust_id=b.cust_id
group by a.cust_id
having count(distinct ordernum) > 1
and max(b.quantity) > avg(b.quantity)
Fiddle
| CUST_ID | ITEMORDERD | SUM |
|---------|------------|-----|
| 1 | 2 | 61 |
I think it will be:
SELECT MAX(c.CustName) as CustName,
MAX(c.Phone) as Phone,
COUNT(DISTINCT o.Item_ID) as CountOfDistinctItems,
SUM(o.Quantity) as SumOfQuantity
FROM Customer as c
JOIN Orders as o on c.Cust_ID=o.Cust_ID
JOIN (SELECT Ordernum, SUM(Quantity) as Order_q_sum
FROM Orders
GROUP BY Ordernum) as oq
ON o.Ordernum=oq.Ordernum
GROUP BY c.Cust_ID
HAVING COUNT(DISTINCT o.Ordernum)>=2
AND
MAX(oq.Order_q_sum)>
(
SELECT AVG(SumQuantity) FROM
(SELECT SUM(Quantity) SumQuantity FROM Orders GROUP BY OrderNum) as t1
)
HOPE THIS CLOSER TO YOUR NEEDS
SELECT x.custname,
x.phone,
Sum(x.itemcnt),
Sum(x.quantity)
FROM (SELECT c.custname,
c.phone,
1 AS itemCnt,
Sum(o.quantity),
Isnull((SELECT Avg(y.quantity)
FROM orders y
WHERE y.cust_id = o.cust_id), 0.00) AvgQty
FROM customer c
LEFT OUTER JOIN orders o
ON c.cust_id = o.cust_id
GROUP BY c.custname,
c.phone,
o.item_id) x
GROUP BY x.custname,
x.phone
HAVING Sum(x.itemcnt) > 1
AND Sum(x.quantity) > x.avgqty

sql join query for multiple tables

I have following tables structure,
cust_info:
cust_id cust_name
1 nikhil
2 sam
bill_info:
bill_id cust_id bill_amount
7 1 10000
8 1 15000
9 2 6000
10 2 4000
paid_info:
paid_id cust_id paid_amount
11 1 5000
12 1 5000
13 2 5000
14 2 5000
now my output should display sum of bill made by customer and total amount paid by that customer and balance amount
output
cust_id total_bill total_paid balance
1 25000 10000 15000
2 10000 10000 0
where,
for example,
for cust_id = 2,
total_bill= 10000 + 15000
total_paid = 5000 + 5000
balance = total_bill - total_paid
what is convenient way to do this in sql? any sample query?
here's what i've already tried
SELECT distinct c.cust_id
, sum(b.bill_amount) as total_bill
, SUM(p.paid_amt) AS totalpaid,sum(b.bill_amount) - SUM(p.paid_amt) AS balance
FROM cust_info c
INNER JOIN bill_info b ON c.cust_id = b.cust_id
INNER JOIN paid_info p ON p.cust_id= b.cust_id group by p.cust_id;
SELECT
cust_info.cust_id,
cust_name,
bill_amount,
paid_amount,
bill_amount - paid_amount AS balance
FROM cust_info
INNER JOIN (
SELECT cust_id, SUM(bill_amount) bill_amount
FROM bill_info
GROUP BY cust_id
) bill_info ON bill_info.cust_id = cust_info.cust_id
INNER JOIN (
SELECT cust_id, SUM(paid_amount) paid_amount
FROM paid_info
GROUP BY cust_id
) paid_info ON paid_info.cust_id = cust_info.cust_id
demo
SELECT c.cust_id,
SUM(b.total_bill),
SUM(p.total_paid),
SUM(c.total_bill) - SUM(p.total_paid)
FROM
cust_info c
LEFT JOIN bill_info b ON (c.cust_id = b.cust_id)
LEFT JOIN paid_info p ON (c.cust_id = p.party_id)
GROUP
BY cust_info.cust_id
SELECT DISTINCT cust_info.cust_id,
sum(bill_amount) AS 'total_bill' ,
sum(paid_amount) AS 'total paid' ,
(SUM(bill_amount) - sum(paid_amount)) AS balance
FROM cust_info
INNER JOIN bill_info ON cust_info.cust_id = bill_info.cust_id
INNER JOIN paid_info ON cust_info.cust_id = paid_info.cust_id
GROUP BY cust_info.cust_id

Join on two related tables

I have two tables: One for Invoices and other for their payments:
tbl_Invoice
tbl_payment
The desire output is as below:
PSUM IPRICE
----------- ------------
312.00 1100.00
Where:
PSUM is Sum of Payments.
IPRICE is Sum of Total_price of that client.
Query I tried is:
select
IsNull(sum(p.amt), 0) PSUM,
IsNull(sum(i.total_price), 0) IPRICE
from tbl_invoice i
left join tbl_payment p
on i.invoice_id = p.invoice_id
and i.client_id = p.client_id
where i.client_id = 5
group by i.invoice_id
order by i.invoice_id
But it gives wrong output:
PSUM IPRICE
----------- ------------
312.00 400.00
0.00 1000.00
Seems like you want this. This gives the total sum of the amt and the total_price with no grouping. Your version groups by the invoice_id which is the difference:
select
IsNull(sum(p.amt), 0) PSUM,
IsNull(sum(distinct i.total_price), 0) IPRICE
from tbl_invoice i
left join tbl_payment p
on i.invoice_id = p.invoice_id
and i.client_id = p.client_id
where i.client_id = 5
See SQL Fiddle with Demo
Another way you could write this is using subqueries:
select
IsNull(sum(p.amt), 0) PSUM,
IsNull(sum(i.total_price), 0) IPRICE
from
(
select sum(total_price) total_price, invoice_id, client_id
from tbl_invoice
group by invoice_id, client_id
) i
left join
(
select sum(amt) amt, invoice_id, client_id
from tbl_payment
group by invoice_id, client_id
) p
on i.invoice_id = p.invoice_id
and i.client_id = p.client_id
where i.client_id = 5
See SQL Fiddle with Demo
Both produce the same result:
| PSUM | IPRICE |
-----------------
| 312 | 1100 |