Trying to display values from multiple tables in SQL - sql

I have two tables in SQL, one of which contains the employee ID (emp_id) and their first, and last name. Another table contains the employee ID with their total sales. I want to see the first name, last name, and their total sales of only those records where the total sales are higher than 25,000. The first table's name is employee, and the second table's name is works_with
The code that I used is:
SELECT employee.first_name, employee.last_name,works_with.total_sales
FROM employee
WHERE employee.emp_id IN (
SELECT works_with.emp_id
FROM works_with
WHERE works_with.total_sales>25000
);
I'm getting the following error:
"Msg 4104, Level 16, State 1, Line 25
The multi-part identifier "works_with.total_sales" could not be bound."
How can I fix this error?
Thanks

Your query still works if writing like this:
SELECT employee.first_name, employee.last_name
FROM employee
WHERE employee.emp_id IN (
SELECT works_with.emp_id
FROM works_with
WHERE works_with.total_sales>25000
);
Your select is failed because it doesn't have the column works_with.total_sales.
You can add works_with.total_sales to your select with the join clause like this:
SELECT employee.first_name, employee.last_name, works_with.total_sales
FROM employee
JOIN works_with
on employee.emp_id=works_with.emp_id
WHERE works_with.total_sales>25000
Or select multiple tables like this:
SELECT employee.first_name, employee.last_name, works_with.total_sales
FROM employee, works_with
WHERE employee.emp_id=works_with.emp_id
and works_with.total_sales>25000
Explain the error
The multi-part identifier "works_with.total_sales" could not be bound
That tells you the works_with.total_sales isn't available in the current selection.
You can't bound it to your selection.
see https://www.w3schools.com/sql/sql_join.asp for join clause in t-SQL

This query might work given your requirements. A JOIN could be used to link those two tables in your question.
select t1.first_name,
t1.last_name,
t2.total_sales
from employees t1
join works_with t2
on t2.emp_id = t1.emp_id
where t2.total_sales > 25000

You can join bth tables and show all rows with where the total_sales is bigger than 2500
SELECT employee.first_name, employee.last_name,works_with.total_sales
FROM employee INNER JOIN works_with ON works_with.emp_id = employee.emp_id
WHERE works_with.total_sales>25000;

Related

Unable to join tables from 2 tables with many to many condition

I have this diagram below, I am trying to first computes the total number of suppliers supplying the specified part then extracts the supplier’s information supplying the specified part.
SELECT count(*) totalCount, s_suppkey, s_name
FROM supplier INNER JOIN part ON s_suppkey = p_suppkey
WHERE p_partkey = 123
GROUP BY s_suppkey, s_name;
But i keep getting this error ORA-00904: "P_SUPPKEY": invalid identifier
Based on your diagram, there is no such column in the part table,
You (probably) need to use the (bridging) table that is part-hidden off to the left of your image that connects the parts and suppliers in a many-to-many relationship.
SELECT COUNT(*) OVER () totalCount,
s_suppkey,
s_name
FROM supplier s
WHERE EXISTS(
SELECT 1
FROM part_supplied_by ps
WHERE s.s_suppkey = ps.s_suppkey
AND p.p_partkey = 123
);

SQL Group By Throwing Up Error (SQL Server)

I have SQL code that throws up an error saying
Error: SQLCODE=-119, SQLSTATE=42803, SQLERRMC=WONUM
The code works fine until I add the group by:
select *
from workorder
left join labtrans on labtrans.refwo=workorder.wonum and labtrans.siteid=workorder.siteid
left join matusetrans on workorder.wonum=matusetrans.refwo and workorder.siteid=matusetrans.tositeid and linetype not in (select value from synonymdomain where domainid='LINETYPE' and maxvalue='TOOL')
left join locations on locations.location = workorder.location and locations.siteid=workorder.siteid
left join person on personid in (select personid from labor where laborcode = labtrans.laborcode)
left join po on workorder.wonum=po.hflwonum and workorder.siteid=po.siteid and workorder.orgid=po.orgid
left join companies on companies.company = po.vendor and companies.orgid=po.orgid
left join pluspcustomer on pluspcustomer.customer=workorder.pluspcustomer
where workorder.wonum='10192'
group by personid
;
if you only GROUP BY personid, you cannot select everything except personid, OR the fields used by aggregate functions such as SUM,MAX, etc
UPDATE
If you just want to see the duplicate personid, you could use:
select personid
from table
group by personid
But be careful here: If you write query like this, the only field that to determine the duplicate records is persionid, if you need to uniquely identify each persionid from different CompanyId, you need to group by persionid, CompanyId, otherwise, same personId from different company will be considered as the duplicate records.
But if you want to delete those duplicate records, you should use ROW_NUMBER()OVER (Partition by persionid Order by your_criteria) to delete the duplicate records. Try to do some searches to see how does that work, usually I prefer to use that function along with the CTE table expression.
if you just need to remove duplicates, use DISTINCT with your query like this:
your query:
SELECT * FROM .....
modify it:
SELECT DISTINCT * FROM .....
Hope it helps.

I am trying to join two table but getting the error as Invalid object name

I want to Write a SQL script, which would return all the Employees in EmployeeMaster table with the columns LastName, City, State and Country.
This is what I tried to execute but it shows error.
SELECT dbo.EmployeeMaster.LastName, dbo.EmployeeDetails.City, State, Country
From dbo.EmployeeMaster
LEFT JOIN EmployeeDetails
ON dbo.EmployeeMaster.ID=dbo.EmployeeDetails.EmployeeID
ORDER BY dbo.EmployeeMaster.LastName
I think you are missing dbo prefixe on your left join no ? Since you are sing it on the ON, ORDER and SELECT
SELECT dbo.EmployeeMaster.LastName, dbo.EmployeeDetails.City, State, Country
From dbo.EmployeeMaster
LEFT JOIN dbo.EmployeeDetails ON dbo.EmployeeMaster.ID=dbo.EmployeeDetails.EmployeeID
ORDER BY dbo.EmployeeMaster.LastName
Not sure which table State & ountry are from, hoping they are not in both table else you need to add their table alias.

How to get the value of max() group when in subquery?

So i woud like to find the department name or department id(dpmid) for the group that has the max average of age among the other group and this is my query:
select
MAX(avg_age) as 'Max average age' FROM (
SELECT
AVG(userage) AS avg_age FROM user_data GROUP BY
(select dpmid from department_branch where
(select dpmbid from user_department_branch where
user_data.userid = user_department_branch.userid)=department_branch.dpmbid)
) AS query1
this code show only the max value of average age and when i try to show the name of the group it will show the wrong group name.
So, How to show the name of max group that has subquery from another table???
You may try this..
select MAX(avg_age) as max_avg, SUBSTRING_INDEX(MAX(avg_age_dep),'##',-1) as max_age_dep from
(
SELECT
AVG(userage) as avg_age, CONCAT( AVG(userage), CONCAT('##' ,department_name)) as avg_age_dep
FROM user_data
inner join user_department_branch
on user_data.userid = user_department_branch.userid
inner join department_branch
on department_branch.dpmbid = user_department_branch.dpmbid
inner join department
on department.dpmid = department_branch.dpmid
group by department_branch.dpmid
) tab_avg_age_by_dep
;
I've done some change on ipothesys that the department name is placed in a "department" anagraphical table.. so, as it needed put in join a table in plus, then I changed your query, eventually if the department name is placed (but I don't thing so) in the branch_department table you can add the field and its treatment to your query
update
In adjunct to as said, if you wanto to avoid identical average cases you can furtherly make univocal the averages by appending a rownum id in this way:
select MAX(avg_age) as max_avg, SUBSTRING_INDEX(MAX(avg_age_dep),'##',-1) as max_age_dep from
(
SELECT
AVG(userage) as avg_age, CONCAT( AVG(userage), CONCAT('##', CONCAT( #rownum:=#rownum+1, CONCAT('##' ,department_name)))) as avg_age_dep
FROM user_data
inner join user_department_branch
on user_data.userid = user_department_branch.userid
inner join department_branch
on department_branch.dpmbid = user_department_branch.dpmbid
inner join department
on department.dpmid = department_branch.dpmid
,(SELECT #rownum:=0) r
group by department_branch.dpmid
) tab_avg_age_by_dep
;
I took a shot at what I think you are looking for. The following will give you the department branch with the highest average age. I assumed the department_branch table had a department_name field. You may need an additional join to get the department.
SELECT db.department_name, udb.dpmid, AVG(userage) as `Average age`
FROM user_data as ud
JOIN user_department_branch as udb
ON udb.userid = ud.userid
JOIN department_branch as db
ON db.dpmbid = udb.dpmbid
GROUP BY udb.dpmid
ORDER BY `Average age` DESC
LIMIT 1

How to use WITH clause and select clause

click here to view screenshot of table
Question: write a query to display the customer number, firstname, lastname for those client where total loan amount taken is maximum and at least taken from 2 bank branch.
I have tried the following query but I'm getting this error
Msg 8120, Level 16, State 1, Line 7
Column 'customer.fname' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Code:
with l as
(
select custid, sum(loan_amount) as tot
from loan
group by custid
having count(bid) >= 2
)
select
concat(c.fname, c.ltname) as name,
max(l.tot)
from
customer as c, l
where
l.custid = c.custid
You need to have a GROUP BY to select both aggregated and non-aggregated data, so you need to decide how you want the data grouped. You could do either
SELECT CONCAT(c.fname,c.ltname) as name, MAX(l.tot)
FROM customer AS c
INNER JOIN l ON l.custid=c.custid
GROUP BY c.fname,c.ltname
or
SELECT CONCAT(c.fname,c.ltname) as name, MAX(l.tot)
FROM customer AS c
INNER JOIN l ON l.custid=c.custid
GROUP BY concat(c.fname,c.ltname)
Please note the following:
I converted the "old" join syntax to the more acceptable INNER JOIN syntax
You probably want a space between the first and late name if you're displaying the results.