I get duplicate data in inner join with 3 tables - sql

I have three tables: Customers, Receipts, Salary
Customers
Id Name
1 john
Receipts
Id Amount
1 500
2 250
3 600
4 700
Salary
Id Amount
1 300
2 300
3 680
Id like to find sum of salary and receipts related to john.
I thought it's simple sql statement like:
select cus.Name, sum(sal.Amount) as Salary, sum(re.Amount) as Recieved
from Customers as cus inner join Salaries as sal on cus.Id = sal.Id
inner join Receipts as re on cus.Id = re.Id
where cus.Id= 1
Group by cus.Name
but I found the result so bigger
Name Salary Recieved
john 6150 4320
When I write the query without sum:
select cus.Name, sal.Amount as Salary, re.Amount as Recieved
from Customers as cus inner join Salaries as sal on cus.Id = sal.Id
inner join Receipts as re on cus.Id = re.Id
where cus.Id= 1
I get these duplicate records
john 500 100
john 500 300
john 500 680
john 250 100
john 250 300
john 250 680
john 600 100
john 600 300
john 600 680
john 700 100
john 700 300
john 700 680
why the inner join behavior like this? I expect to get the records one time but it repeated 4 times!
Did I have to try sub-select queries?

The query looks right.
http://www.sqlfiddle.com/#!9/1b5157/1
There's a fiddle with your approximate query and it works as expected. So as the person before said, since you have CustomerOrSupplier, you might be joining to the wrong table

select cus.Name,
sum(sal.Amount) as Salary,
sum(re.Amount) as Recieved
from Customers as cus
inner join Salary as sal
on cus.Id = sal.Id
inner join
Receipts as re
on cus.Id = re.Id
Group by cus.Name;
Demo
http://sqlfiddle.com/#!18/956fb/10

I see that the issue happens to be one of the tables names.
Change the following:
from Customers as cus inner
join Salaries as sal
on cus.Id = sal.Id
to:
from Customers as cus inner
join Salary as sal
on cus.Id = sal.Id

Related

How to apply join on tables while using having function?

There are two tables - trans and customer.
trans
customerid
pdate
purchase
1
11-01-2021
200
2
13-02-2021
400
1
18-01-2021
400
3
31-01-2021
600
4
23-03-2021
700
customer
customerid
firstname
lastname
1
raj
sharma
2
rahul
dev
3
riya
sen
4
rose
menon
The question is -
Find the firstname, lastname and sum of the purchase of the customers where sum of the purchase is greater than 500 in the month of January (Without using any CTE).
My take on this was -
SELECT
c.firstname,
c.lastname,
SUM( t.purchase )
FROM
customer c
INNER JOIN trans t ON c.id = t.id
GROUP BY
c.firstname,
c.lastname
HAVING
SUM( t.purchase ) > 500;
But this ignores the customers with id 1. The customerid 1 has made a purchase twice and the sum of his purchase is greater than 500.
I am using PostgreSQL.

Need help fetching data from DB2

S.no
emp_id
emp_name
Dept
1
100
John
Sales
2
100
John
Accounts
3
200
Mike
Sales
4
300
Mark
Sales
5
300
Mark
Accounts
6
400
Tom
Sales
I need to pull all the emp_id who are linked ONLY to Sales Dept and ignore the ones that are in both Sales and Accounts. I am using DB2 z/os. Any suggestions would be helpful? Thanks in advance.
An anti-join will produce the result you want.
For example:
select s.*
from employee s
left join employee a on a.emp_id = s.emp_id and a.dept = 'Accounts'
where s.dept = 'Sales' and a.emp_id is null
For good performance you can try adding the index:
create index ix1 on employee (emp_id, dept);

SQL Query to Return Total Number of Lines and Number of Items

I am running a query on two tables that needs to return the total number of lines in each sales order and a total of the items ordered.
A simplified version of the SalesOrder table is constructed like this:
SalesOrderID
Customer
SODate
102
Bob Smith
12/15/2021
101
Jane Doe
12/05/2021
100
Sarah Joy
12/01/2021
The second table, SalesOrderLine, contains the line items in the sales order:
SalesOrderID
LineNumber
Item
Quantity
100
1
Nuts
5
100
2
Bolts
10
100
3
Washers
3
101
1
Screws
15
102
1
Nails
25
102
2
Hooks
5
The result of the query would look like this:
SalesOrderID
SODate
Customer
TotalLines
TotalItems
102
12/15/2021
Bob Smith
2
30
101
12/05/2021
Jane Doe
1
15
100
12/01/2021
Sarah Joy
3
18
I am locking up on how to use the query to return the Total Number of Lines and Total Number of Items per SalesOrderID.
SELECT SalesOrder.SalesOrderID, SalesOrder.SODate, SalesOrder.SOCustomer
?? Total Number of Lines and Total Number of Items ??
FROM SalesOrder
INNER JOIN SalesOrders ON SalesOrder.SalesOrderID = SalesOrderLine.SalesOrderID
ORDER BY SalesOrderID
You can use apply :
select so.*, soo.*
from salesorder so cross apply
( select count(*) as Totallines, sum(soo.quantity) as TotalQty
from SalesOrders soo
where soo.SalesOrderID = so.SalesOrderID
) soo;
You are almost done, except the aggregation.
Query
select so.SalesOrderID, so.SODate, so.SOCustomer,
count(sol.LineNumber) as TotalLines, sum(sol.Quantity) as TotalItems
from SalesOrder as so
join SalesOrderLine as sol
on so.SalesOrderID = sol.SalesOrderID
group by so.SalesOrderID, so.SODate, so.SOCustomer
order by SalesOrderID;

Group Join between three tables to get the percentage

I have three tables Attendance, Employee, Sector
Employee Table
EmiId -Name -SectorId
123 ABC 1
231 BCD 2
125 WER 1
Attendance
AttId -EmpId -Dt
1 123 12/12/2014 9:00
2 231 12/12/2014 10:00
Sector
SectorId -SectorName
1 North Sector
2 East Sector
my query is
SELECT COUNT(Attendance.Emp_Id) as AttCount,(select COUNT(*) from Employee) as EmpCount
FROM Employee INNER JOIN
Sector ON Employee.SectorId = Sector.SectorId INNER JOIN
Attendance ON Employee.EmpId = Attendance.EmpId
group by Sector.SectorId
and i keep getting same number of employees for both instead so the (select COUNT(*) from Employee)- EmpCount seems to be incorrect.I keep getting the same number for both the sectors. Although the Attcount seems to work fine.
Please help. Thanks in advance.
You just making select count from the same table - do not expect other results.
Perhaps someone could do it better
SELECT COUNT(Attendance.Emp_Id),COUNT(case when Employee.empid=attendance.attid then 1 else 0 end)
FROM Employee JOIN Sector ON Employee.SectorId = Sector.SectorId
LEFT JOIN Attendance ON Employee.EmpId = Attendance.Emp_Id
group by Sector.SectorId
Maybe you need LEFT JOIN with Attendance
SELECT COUNT(Attendance.Emp_Id),(select COUNT(*) from Employee)
FROM Employee JOIN Sector ON Employee.SectorId = Sector.SectorId
LEFT JOIN Attendance ON Employee.EmpId = Attendance.EmpId
group by Sector.SectorId

sql query for getting data from two related tables

I have two tables, employee and inventory. One employee can have zero or more inventories.
I would like to list employee information along with at most one inventory information
and count of inventories belongs to one employee.
employee table
emp_num last_name first_name
-----------------------------------
100 john smith
101 mike pet
102 jes lyoid
inventory table
inv_num emp_num
---------------------------
12 100
13 100
15 100
30 102
desired Output
emp_num last_name invnum count(inv_num)
--------------------------------------------------------------------------
100 john 12 3
101 mike - 0
102 jes 30 1
What sql query can I use in this case?
Try this:
SELECT emp_num, last_name, MAX(inv_num) AS invnum, COUNT(inv_num) AS inv_count
FROM employee e LEFT OUTER JOIN inventory i ON e.emp_num = i.emp_num
GROUP BY e.emp_num, e.last_name
You could do something like this
Select E.Emp_Num,
e.Last_name,
MIN(Inv_Num) AS OldestInv,
COUNT(Inv_Num) AS TotalInv
FROM Employee E
LEFT OUTER JOIN Inventory I
(E.Emp_Num = I.Emp_Num)
GROUP BY E.Emp_Num, E.Last_Name
This will give you the minimum invoice number and the total count. The left outer join is the key
SELECT
e.emp_num,
e.last_name,
IFNULL(MAX(i.inv_num),'-') AS 'invnum',
COUNT(i.inv_num) AS 'count(inv_num)'
FROM
employee e LEFT JOIN inventory i
ON e.emp_num = i.emp_num
GROUP BY
e.emp_num, e.last_name