Access database returns double SUM for field Income - ms-access

I have the following query in access 2003 mdb.
SELECT Company.Name, Company.Address, Place.Name_of_Place, Sum(Income.Value) AS Income, Sum(Invoice.Value) AS Invoice
FROM ((Company LEFT JOIN Invoice ON Company.CompanyID = Invoice.CompanyID) LEFT JOIN Income ON Company.CompanyID = Income.CompanyID) INNER JOIN Place ON
Place.Postal = Company.Postal
GROUP BY Company.Name, Company.Address, Place.Name_of_Place, Company.CompanyID
HAVING ((iif(IsNull(Sum(Invoice.Value)), 0, Sum(Invoice.Value)) - iif(IsNull(Sum(Income.Value)), 0, Sum(Income.Value))) > 0)
ORDER BY Company.Name;
Income field value is 500, but query returns 1000.
There must be something with those Left joins that this Income table is twice searched.
How to solve this?
I'm thinking to in my program do simple division by 2 for this column, but I'd rather like to solve this on database level.
Regards,
Vajda

When you join the Company with the Invoice, the result will have as many rows as the rows in Invoice. So if a company has 2 invoices, you will have 2 rows.
Then, when you join that with the Income (which I am not sure how many rows per company it has) the result will be 2 rows for each row of Income.
You will have to resort to sub-queries, like this:
SELECT
Company.Name,
Company.Address,
Place.Name_of_Place,
(SELECT SUM(Income.Value) FROM Income WHERE Income.CompanyID=Company.CompanyID) AS Income,
(SELECT SUM(Invoice.Value) FROM Invoice WHERE Invoice.CompanyID=Company.CompanyID) AS Invoice
FROM
Company INNER JOIN Place ON Place.Postal = Company.Postal
WHERE
Invoice - Income > 0
ORDER BY
Company.Name;

Related

Need to know how to select customer names where their purchase price is greater than 100

i have a sql homework. i Have built a small database with 3 tables(in images).I need to select customer names that have purchased for more than 100 within last month.All purchases are separated.
I tried using using SUM
SELECT customer.CustomerName
FROM customer INNER JOIN
sales
ON customer.id=sales.CustomerId
HAVING SUM(sales.SalesPrice > 100)
In my database there are customers that the sum of Sales price is greteater than 0 but SQL return blank outputenter image description here
Try this:
SELECT customer.customerName FROM customer
INNER JOIN sales ON customer.id = sales.customerId
GROUP BY customerName
HAVING SUM(sales.SalesPrice) > 100;
The correct syntax looks like this:
SELECT c.CustomerName
FROM customer c INNER JOIN
sales s
ON c.id = s.CustomerId
GROUP BY c.id, c.CustomerName
HAVING SUM(s.SalesPrice) > 100;
I need to select customer names that have purchased for more than 100 within last month
SELECT C.CustomerName
FROM customer AS C INNER JOIN sales AS S ON C.id = S.CustomerId
WHERE S.SalesDate >= '20190701' AND S.SalesDate < '20190801' --within last month
GROUP BY C.CustomerName
HAVING SUM(S.SalesPrice) > 100 --Sum of purchases greater than 100
This sort of requires looking at the picture link, which should be included as part of the question, not as a link. For example, the link could expire or the link could be blocked by an organization's firewall.
The second part of this task needs me to write a query that return an item name that has the most transaction count. I need to know which ItemId.Sales has the most values. Currently I have this code
SELECT ItemName
FROM item
INNER JOIN sales ON item.id = sales.ItemID
but I need to know how to count those ItemID's and which ID has the biggest count

SQL count and sum issue

I have 2 tables with data.
The first table cus contains the customer data. The second table invoice contains the invoices created by the customer.
I want to select the total created invoices and the total sum of the invoices per customer.
Here is what I have:
SELECT cus.cus_id, cus.name_cus, count(invoice.id) as id2, CONCAT('€ ', ROUND(SUM(invoice.total),2)) as total, cus.id
FROM cus
LEFT OUTER JOIN invoice ON cus.cus_id = invoice.cus_id
WHERE cus.user_id='2'
GROUP BY cus.cus_id
To test this I have added some data to my database. The first customer has 2 invoices with a total sum of 100 (50+50).
The second customer has 3 invoices with a total sum of 30 (10+10+10).
But the SQL code dont shows me these results.
The response is for customer 1: total invoices = 1, total = 50
The response is for customer 1: total invoices = 0, total = (empty)
Does someone know what is wrong with my SQL statement?
The database type I am using is MySQL.
Here is a sample: http://sqlfiddle.com/#!9/a9f9f/1
Try grouping up your invoice count and sum as a subquery first, like:
SELECT cus.cus_id, cus.name_cus, inv.invoice_count, inv.invoice_total, cus.id
FROM cus
LEFT OUTER JOIN
(
SELECT inv.cus_id,
COUNT(inv.id) AS invoice_count,
CONCAT('€ ', ROUND(SUM(inv.total),2)) AS invoice_total
FROM invoice inv
GROUP BY inv.cus_id
) inv
ON cus.cus_id = inv.cus_id
WHERE cus.user_id='2'
If you're using SQL Server then your query should be like this --
SELECT C.cus_id
,C.name_cus
,Count(I.id) AS NumberOfInvoices
,IsNull(Sum(I.Price), 0) AS TotalPrice
FROM Customer C
LEFT JOIN Invoice I ON C.cus_id = I.cus_id
GROUP BY C.cus_id, C.name_cus
ORDER BY C.cus_id;
This is a simple sql Query as i understood your problem. I assumed CustomerID is in both tables. I think this Query will help you.
select i.CustomerID,i.CustomerName,COUNT(i.InvoiceID) as A, SUM(i.invoicetotal) as b
from Cus c,Invoice i
where i.CustomerID=c.CustomerID
group by i.CustomerID

Complex relational mysql query with sum

I'm struggling to construct a mysql query. I need to obtain data from two tables:
Table cash
----------
id
income_money
cashdata_id
paymentterm
_
Table cash_data
------------
id
total
user
date
So cash_data holds the payments that need to be paid, and cash holds the registered payments that are already processed.
When a payment is marked as complete, the relevant row in cash_data is updated with the associated user ID and date.
The idea is to make a query from cash_data and check which payments have some income money paid but that are not marked as complete (i.e. doesn't have user and date fields data).
Okay, it was simple to here.
The problem is that there may be several cash table rows relating to one cash_data row and I have to select all cash_data rows, and then select the relational cash rows and sum the cash.income_money - because I need to compare cash.total with cash.income_money.
Query summing money:
This also uses a left join to show rows that may not yet have payments.
SELECT cd.id,
cd.total,
sum(c.income_money) AS "Total Income"
FROM cash_data cd
LEFT JOIN cash c ON c.cashdata_id = cd.id
GROUP BY cd.id,
cd.total;
First query which is rather simple:
select cd.id, cd.total, sum(c.income_money) as "Total Income" from
cash_data cd left join cash c
on c.cashdata_id = cd.id
group by cd.id, cd.total;
SQL Fiddle: http://www.sqlfiddle.com/#!2/800b4/6
You need to join the two tables. Like this:
SELECT SUM(cash.income_money), cash_data.total, cash_data.id
FROM cash_data
JOIN cash ON cash.cashdata_id=cash_data.id

MySQL Query - listing data from 2 tables where NOT EXISTS

I am trying to calculate point usage by customers of an online store. Over time, customers acquire points. As points are redeemed, the value of the customer.points is modified to reflect points remaining to redeem. Any additional points acquired are also added to customer.points. Because of this, the only true mechanism for determining the number of points a customer has had over the lifetime of an account is to SUM total usage with remaining points (order.total + customer.points).
The query below returns the desired results, BUT ONLY FOR THOSE CUSTOMERS WHO HAVE REDEEMED POINTS. What I would like, since ALL customers have points, is to also be able to return the points balance for those WHO HAVE NOT REDEEMED points.
SELECT customer.store_id, customer.customer_id, `order`.total + customer.points
AS allpoints, customer.firstname, customer.lastname
FROM `order`
INNER JOIN customer ON `order`.customer_id = customer.customer_id
WHERE (customer.store_id =3)
GROUP BY customer.customer_id
It sounds like you need to use an left outer join, which will return all rows for the table on the left side of the join, and only return rows for the table on the right side if records exist. This does mean that you'll need to handle null values for the order table when a record doesn't exist.
SELECT
customer.store_id,
customer.customer_id,
isnull(order.total, 0) + customer.points AS allpoints,
customer.firstname,
customer.lastname
FROM customer
LEFT OUTER JOIN order ON order.customer_id = customer.customer_id
WHERE (customer.store_id =3)
GROUP BY customer.customer_id

mysql - How to fix this query?

I am really having a headache since the other day on how to fix this mysql statement to get my desired result. I also want to inform that I am new to mysql and prorgramming.
I have 4 tables CUSTOMER, CUSTOMER_ACCT_SETTING, DEBT, and PAYMENT.
Here are the 4 tables with their record so you can relate.
CUSTOMER
CUSTOMER_ACCT_SETTING
DEBT
PAYMENT
When I run this mysql statement:
SELECT C.CUSTOMER_ID, C.NAME, C.ADDRESS, C.CONTACT_NUMBER,
SUM(((CAS.INTEREST_RATE / 100) * D.AMOUNT) + D.AMOUNT) - COALESCE(SUM(P.AMOUNT), 0) AS CURRENT_BALANCE
FROM CUSTOMER C
INNER JOIN CUSTOMER_ACCT_SETTING CAS ON (C.CUSTOMER_ID = CAS.CUSTOMER_ID)
LEFT JOIN DEBT D ON (C.CUSTOMER_ID = D.CUSTOMER_ID)
LEFT JOIN PAYMENT P ON C.CUSTOMER_ID = P.CUSTOMER_ID
GROUP BY (C.CUSTOMER_ID)
ORDER BY C.NAME
The result is below:
PS: The result is ordered by name.
My question is:
1.) Why did I get a negative result on the CURRENT_BALANCE column in the first row? I am expecting the result to be around 16374.528.
My desired result is like this:
You are projecting your payments through all your debts by doing a join with both tables at the same time. So you essentially get 5 applications of your payment on customer 4 and zero applications on all the other customers. (so NULL on P.AMOUNT yields X - NULL = NULL). To see this, remove the "GROUP BY" and the "SUM" and just return your amounts paid and debited. Then if you group/sum these results manually by customer, you'll see what's going on.
To get the results you expect, you will need to use subqueries or some other mechanism like temporary tables. Something like this:
SELECT C.CUSTOMER_ID,
(SELECT SUM(P.AMOUNT) FROM PAYMENT P
WHERE P.CUSTOMER_ID = C.CUSTOMER_ID) AS TOTAL_PAID_BY_CUSTOMER
FROM CUSTOMER C
The answer to #1 is that each row in your result set has the payment attached to it. That is, for customer #1, you're getting three instances of the 8132.