SQL Group by prevents summing across multiple records - sql

I am trying to sum the amount paid across multiple entries in the Payment table and show who the buyers were for that Order
so if two people made payments on one order it would show their combined payments and show who the people who made the payment were. So if Bob and Sue made 10 dollar payments on a 30 dollar bill it would show
Order Buyer Paid Owes
1 Bob 20 10
1 Sue 20 10
but i'm currently at
Order Paid Owes
1 20 10
How do I add in the buyers? possibly with a join?
Currently I have.
Select Order.Orderid, sum(Payment.amount) as "Paid", Order.Price-sum(Payment.amount) as "Owes"
from order, payment
where payment.orderId = order.orderid
group by (order.orderid, order.price)
payment has a buyerId and orderid as foreign keys since it is an m to n relation.

As you mention in your comment when you join the buyer it does not give you the desired output which is the sum of all payments. To get the buyers and the sum of all payments joining another instance of the payments table and using that to calculate the sum will do the trick.
SELECT
Order.Orderid,
Buyer.Name,
SUM(PaymentSum.amount) AS 'Paid',
Order.Price-SUM(PaymentSum.amount) AS 'Owes',
FROM
Order
JOIN Payment
ON Order.Orderid = Payment.Orderid
JOIN Buyer
ON Payment.BuyerId Buyer.BuyerId
JOIN Payment AS PaymentSum
ON Order.Orderid = PaymentSum.Orderid
GROUP BY
Order.Orderid,
Order.Price,
Buyer.Name

Related

database and ER diagram for this scenario

A company serves many clients through selling different products. These products are sold by sales persons who then take 0.1% out of every deal they make. Sales persons are not paid monthly salary but are on basic pay, i.e, 1200 + commission in sales. There are total 12 employees , 10 sales persons and 2 managers. Each manager has 5 sales persons working under him. The company requires the following information:
each sales record made by sales person with date
sales person total income every month
bonus to those sales persons who make sale more than 1 million rupees in any year
no. of sales persons having gmail account
The main problem i'm struggling with is to calculate the salary of the
sales person. I've got products cost in the products table and how
many products a sales person sold in the sales-record table. But this
salary column is in salesperson table. How can i calculate salary by
using data from two different tables?
If you can calculate the dynamic % and the static salary, then all you have to do is to use UNION ALL
SQL Fiddle
MS SQL Server 2014 Schema Setup:
Query 1:
SELECT sum(t.salary) annual_salary
FROM
(
-- the select for the dynamic part
select (15500000*0.001) AS salary -- FROM table
union all
-- the select for the static one
select 30000 AS salary -- FROM table
) AS t
Results:
| annual_salary |
|---------------|
| 45500 |

SQL SUM problems

I have this Query:
Select Denumire,Sum(Livrari.Cantitate)as Stoc,
isnull(Sum(Facturi_Emise.Cantitate),0) as 'Sold',
isnull(Sum(Livrari.Cantitate),0)-isnull(sum(Facturi_Emise.Cantitate),0) As 'Stoc After Sales',
Livrari.Id_Depozit
From Livrari
Left join Produse On Livrari.Id_Produs=Produse.Id_Produs
Left join Facturi_Emise On Produse.Id_Produs=Facturi_Emise.Id_Produs
group by Denumire, Livrari.Id_Depozit
order by Denumire
I need to get the Stock, the quantity of the items that are required to be sold, and what I got in the 2 deposits after the items are sold. But in the table "Livrari" I got the same item in both deposit, with the amount of 300 for deposit 1, and 300 for deposit 2 and when I make the sum and group by Id_Depozit I get that item with the amount of 600 in deposit 1 and 600 in deposit 2, same is for table Facutri_Emise as I should take only 250 items from deposit 1 and 300 from deposit 2, it takes 550(250+300) from both deposit and I got the Stoc after Sale 50 for each, instead of 50 for deposit 1 and 0 for deposit 2.
fiddle
My problem is that the result in row 8 and 9(that means Pahare) in column Stoc should be 300 for each. In next column Sold, row 8 should be 250 and for row 9 300. In the end, in column Stoc after Sale should be the difference, as row 8=50, row 9=0.
I mean each time a products repeats, my query is gonna make the sum and put the same value in deposit 1 and in deposit 2, as I give different values for each deposit it should show me the correspondent values. A supplier will bring a certain amount if items(let's say apples) into deposit 1 and another supplier will bring another amount of apples in deposit 2. When the bill is made("Facturi_Emise") for the client I should sent an amount of apples from deposit 1 and another from deposit 2 and I wanna see what amount remains in one deposit,and what remains in other one.
Here it is.
It is not ordered by deposit numbers,but it's okey.
SELECT Produse.Denumire,
Isnull(a.suma,0) AS Intrari,
Isnull(b.suma,0) AS Iesiri,
isnull(a.suma,0) - isnull(b.suma,0) AS Stoc
FROM Produse
LEFT JOIN
(SELECT ID_Produs, Sum(Cantitate) AS suma FROM Livrari GROUP BY ID_Produs)
AS a
ON Produse.ID_Produs = a.ID_Produs
LEFT JOIN
(SELECT ID_Produs, Sum(Cantitate) AS suma FROM Facturi_Emise GROUP BY ID_Produs)
AS b
ON Produse.ID_Produs = b.ID_Produs
SOLLUTION
Select Denumire,Sum(Livrari.Cantitate)as Stoc,
SUM(ISNULL(Facturi_Emise.Cantitate,0)) as 'Sold',
SUM(ISNULL(Livrari.Cantitate,0))-SUM(ISNULL(Facturi_Emise.Cantitate,0)) As 'Stoc After Sales',
Livrari.Id_Depozit
From Livrari
Left join Produse On Livrari.Id_Produs=Produse.Id_Produs
Left join Facturi_Emise On Produse.Id_Produs=Facturi_Emise.Id_Produs
and Livrari.Id_Depozit=Facturi_Emise.Id_Depozit
group by Denumire, Livrari.Id_Depozit
order by Denumire
You need ceck null before sum, soo first ISNULL and then SUM.
If you SUM and one is null then all SUM will be null.

SQL Inner Join query

I have following table structures,
cust_info
cust_id
cust_name
bill_info
bill_id
cust_id
bill_amount
bill_date
paid_info
paid_id
bill_id
paid_amount
paid_date
Now my output should display records (1 jan 2013 to 1 feb 2013) between two bill_dates dates as single row as follows,
cust_name | bill_id | bill_amount | tpaid_amount | bill_date | balance
where tpaid_amount is total paid for particular bill_id
For example,
for bill id abcd, bill_amount is 10000 and user pays 2000 one time and 3000 second time
means, paid_info table contains two entries for same bill_id
bill_id | paid_amount
abcd 2000
abcd 3000
so, tpaid_amount = 2000 + 3000 = 5000 and balance = 10000 - tpaid_amount = 10000 - 5000 = 5000
Is there any way to do this with single query (inner joins)?
You'd want to join the 3 tables, then group them by bill ids and other relevant data, like so.
-- the select line, as well as getting your columns to display, is where you'll work
-- out your computed columns, or what are called aggregate functions, such as tpaid and balance
SELECT c.cust_name, p.bill_id, b.bill_amount, SUM(p.paid_amount) AS tpaid, b.bill_date, b.bill_amount - SUM(p.paid_amount) AS balance
-- joining up the 3 tables here on the id columns that point to the other tables
FROM cust_info c INNER JOIN bill_info b ON c.cust_id = b.cust_id
INNER JOIN paid_info p ON p.bill_id = b.bill_id
-- between pretty much does what it says
WHERE b.bill_date BETWEEN '2013-01-01' AND '2013-02-01'
-- in group by, we not only need to join rows together based on which bill they're for
-- (bill_id), but also any column we want to select in SELECT.
GROUP BY c.cust_name, p.bill_id, b.bill_amount, b.bill_date
A quick overview of group by: It will take your result set and smoosh rows together, based on where they have the same data in the columns you give it. Since each bill will have the same customer name, amount, date, etc, we are fine to group by those as well as the bill id, and we'll get a record for each bill. If we wanted to group it by p.paid_amount, though, since each payment would have a different one of those (possibly), you'd get a record for each payment as opposed to for each bill, which isn't what you'd want. Once group by has smooshed these rows together, you can run aggregate functions such as SUM(column). In this example, SUM(p.paid_amount) totals up all the payments that have that bill_id to work out how much has been paid. For more information, please look at W3Schools chapter on group by in their SQL tutorials.
Hope I've understood this correctly and that this helps you.
This will do the trick;
select
cust_name,
bill_id,
bill_amount,
sum(paid_amount),
bill_date,
bill_amount - sum(paid_amount)
from
cust_info
left outer join bill_info
left outer join paid_info
on bill_info.bill_id=paid_info.bill_id
on cust_info.cust_id=bill_info.cust_id
where
bill_info.bill_date between X and Y
group by
cust_name,
bill_id,
bill_amount,
bill_date

Trying to count # distinct values of a field based on value of a different field

Looking for some help with my SQL query. I am trying to find a way to specify cases in which a customer purchases or sells at two different stores, but if they purchase at one store and sell at another, I don't care or want that to count.
I have tried this -
Select count(distinct store) OVER(Partition BY Customer)
but it doesn't like the distinct and causes an error. When I dont specify distinct, it will give me the count of all observations of that customer, instead of just the count of # of stores that they purchased from, or sold to.
Based on the data below, customer D is the type im looking to filter for.
My Raw Data:
Customer Type Qty Store
A Purchase 1 2
A Purchase 2 2
A Sale 3 1
B Sale 24 1
B Sale 12 1
C Purchase 4 2
D Sale 12 2
D Purchase 4 2
D Purchase 2 1
D Purchase 2 1
Any ideas?
select customer
from your_table
group by customer, type
having count(distinct store) > 1
Don't you just want to GROUP?
Select Count(store) FROM Blah GROUP BY Customer, Store
Edit: Ah I see what you want - you want a count of store over customer, sorry misread it!

MySQL - Finding out Balancing Figure From 2 Tables

I have 2 tables like this:
Stock Table
product_id bigint(20)
qty float
Sales Table
product_id bigint(20)
qty float
Sample Data
Stock Table
product_id---qty
1---10
2---11
3---20
4---50
1---10
3---10
Sales Table
product_id---qty
1---2
2---5
3---20
4---40
1---7
I want the following Output after running the Query
product_id---qty
1---11
2---6
3---10
4---10
Well, as spender ask I am trying to more clear the situation.
First of All, let's think that I store
10 quantity of product 1
11 quantity of product 2
20 quantity of product 3
50 quantity of product 4
10 quantity of product 1 (now I have total 20 of product 1)
10 quantity of product 3 (now I have total 30 of product 3)
Secondly, let's think that I sell
2 quantity of product 1
5 quantity of product 2
20 quantity of product 3
40 quantity of product 4
7 quantity of product 1 (now I have sold total 9 of product 1)
Thirdly, I want to know how much stock is now in my hand
11 quantity of product 1 (20-9 = 11)
6 quantity of product 2 (11-5 = 6)
10 quantity of product 3 (30-20 = 10)
10 quantity of product 4 (50-4 = 10)
My Question is: To find out this stock what is the Query?
Thanks in Advance for answering my question.
This answer works in Oracle - don't have MySql so can't test there
select product_id, sum(qty) from
(
select product_id, qty from stock
union all
select product_id, (-1 * qty) from sales
) as a
group by prod
You question is lacking detail and looks like it might even contain typos in the presented data. I'm going to make the assumption you are trying to calculate the diff between stock quantities and sales quantities, despite your data not actually supporting this (!!!). It looks like you require the following:
select
st.product_id,
sto.qty-st.qty
from
salesTable as st
join stockTable as sto on sto.product_id=st.product_id
Chris's answer is absolutely correct. But for the information I want to add this one which I found on NET.
SELECT tunion.product_id, (
(IFNULL((SELECT SUM(s.qty) FROM stock s WHERE s.product_id=tunion.product_id),0))-
(IFNULL((SELECT SUM(p.qty) FROM sales p WHERE p.product_id=tunion.product_id),0)))
AS quantity
FROM (SELECT DISTINCT s.product_id FROM stock s
UNION ALL SELECT DISTINCT p.product_id FROM sales p)
AS tunion GROUP BY tunion.product_id