How to use WITH clause and select clause - sql

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.

Related

Trying to display values from multiple tables in 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;

Not a Group by expression error [joining tables]

Group by not working when I tried to get maximum of the value column grouped with different subject names & staff names.
The select query inside first brace works fine and I'm getting the desired output from that. But, I'm not able to get maximum value for each staff, subject from that.
select staff_name, subject_name, max(value) from
(select Staff.staff_name, Subject.subject_name, Mark.value as value
from ((staff inner join subject on Staff.staff_id=Subject.staff_id)
inner join Mark ON Mark.subject_id=Subject.subject_id)
group by subject_name);
Error is:
ORA-00979: not a GROUP BY expression
Seems you have wrong sequence for nested ()
and you have missed a not aggregated column in group by
select t.staff_name, t.subject_name, max(t.value)
from (
select Staff.staff_name, Subject.subject_name, Mark.value as value
from staff
inner join subject on Staff.staff_id=Subject.staff_id
inner join Mark ON Mark.subject_id=Subject.subject_id
) t
group by t.staff_name, t.subject_name;
Looks like you just need this:
select st.staff_name, su.subject_name, max(mk.value)
from staff st
join subject su
on su.staff_id = st.staff_id
join mark mk
on mk.subject_id = su.subject_id
group by st.staff_name, su.subject_name

Calculated Field Using Group By Subquery

I have one table which holds Lessons with theirs attributes such as DepId and FieldId. I have two tables also, about Lesson Departments and Lesson Fields. I need to calculate lesson's weekly times percentage's based on DepId and FieldId. My query as follows:
Select a.FieldName, b.DepName, sum(LessonWeeklyTime), ((sum(LessonWeeklyTime))*100)/(select LessonDep, sum(LessonWeeklyTime)
From Lessons
Group By LessonDep)
from Lessons l, Departments b, Fields a
Where l.LessonDep=b.DepId
And l.LessonField=a.FieldId
Group By b.DepName,a.FieldName
But I am getting error:
Msg 116, Level 16, State 1, Line 2
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
Appreciate for help.
Never use commas in the FROM clause. Always use proper, explicit, standard JOIN syntax. It is the 21st Century, after all.
You should be doing this with window functions:
select f.FieldName, d.DepName, sum(LessonWeeklyTime),
(sum(LessonWeeklyTime) * 100.0 /
sum(sum(LessonWeeklyTime)) over (partition by d.depName)
from Lessons l join
Departments d
on l.LessonDep = d.DepId join
Fields f
on l.LessonField = f.FieldId
Group By d.DepName, f.FieldName
As the error message states, you may only have one column in your subquery. Try it that way:
Select a.FieldName, b.DepName, sum(LessonWeeklyTime), ((sum(LessonWeeklyTime))*100)/(select sum(LessonWeeklyTime)
From Lessons
Group By LessonDep)
from Lessons l, Departments b, Fields a
Where l.LessonDep=b.DepId
And l.LessonField=a.FieldId
Group By b.DepName,a.FieldName
Check this:
Select a.FieldName, b.DepName, sum(LessonWeeklyTime), ((sum(LessonWeeklyTime))*100)/ sum(c.LessonWeeklyTime)
from Lessons l, Departments b, Fields a ,(select LessonDep, sum(LessonWeeklyTime) LessonWeeklyTime
From Lessons
Group By LessonDep) c
Where l.LessonDep=b.DepId
And l.LessonField=a.FieldId
And l.LessonDep=c.LessonDep
Group By b.DepName,a.FieldName
This gets the time by necessary codes from 1 table and uses a window function for the percentage. It groups/calculates by the IDs rather than descriptions to improve performance and reduce chance of errors on poor labelling/nulls:
WITH CTE AS( SELECT LESSONDEP, LESSONFIELD, SUM(LESSONWEEKLYTIME) AS [TIME]
FROM [LESSONS]
GROUP BY LESSONDEP, LESSONFIELD)
SELECT F.FIELDNAME, D.DEPNAME, L.[TIME], (L.[TIME]*100.0) / (SUM(L.[TIME]) OVER (PARTITION BY L.LESSONDEP) AS [PERCENTAGE]
FROM CTE L
INNER JOIN DEPARTMENTS D ON L.LESSONDEP = D.DEPID
INNER JOIN FIELDS F ON L.LESSONFIELD = F.FIELDID

sql join and count error

I am trying to count how many employees there are at certain stores and group by store code from 2 tables containing, 1-Emplyee.EMP_CODE,STORE_CODE Table and 2-STORE.store_code...
(STORE tbl-does not contain EMP_CODE) SO I may not even be on the right track.
SELECT c.EMP_CODE,c.STORE_CODE,s.STORE_CODE,COUNT(c.EMP_CODE)
FROM EMPLOYEE c
LEFT OUTER JOIN STORE s
on c.STORE_CODE=s.STORE_CODE
GROUP BY s.STORE_CODE
;
Keep Getting an error:
Msg 8120, Level 16, State 1, Line 1 Column 'EMPLOYEE.EMP_CODE' is
invalid in the select list because it is not contained in either an
aggregate function or the GROUP BY clause.
As the error states, you need to have all non-aggregate columns in your GROUP BY, from those that you are selecting.
Option 1: Add all of the non-aggregate columns to your GROUP BY
SELECT c.EMP_CODE,c.STORE_CODE,s.STORE_CODE,COUNT(c.EMP_CODE)
FROM EMPLOYEE c
LEFT OUTER JOIN STORE s
on c.STORE_CODE=s.STORE_CODE
GROUP BY c.EMP_CODE,c.STORE_CODE,s.STORE_CODE;
Option 2: Remove all non-grouped columns from your original SELECT
SELECT s.STORE_CODE, COUNT(c.EMP_CODE)
FROM EMPLOYEE c
LEFT OUTER JOIN STORE s
on c.STORE_CODE=s.STORE_CODE
GROUP BY s.STORE_CODE;
Option 3: Use a nested select to COUNT(c.EMP_CODE) and only GROUP BY s.STORE_CODE, while still being able to select all of the columns you want. Something like:
SELECT c.EMP_CODE,c.STORE_CODE,s.STORE_CODE,A.Count_Emp
FROM EMPLOYEE c
LEFT OUTER JOIN STORE s
on c.STORE_CODE=s.STORE_CODE
LEFT OUTER JOIN (
SELECT s.STORE_CODE, COUNT(c.EMP_CODE) as 'Count_Emp'
FROM EMPLOYEE c
LEFT OUTER JOIN STORE s
ON c.STORE_CODE=s.STORE_CODE
GROUP BY s.STORE_CODE
) A on A.STORE_CODE = c.STORE_CODE;
You are missing all the columns from your GROUP BY Clause. That should fix it!

sql count statement leads to wrong value

select count(d.Games_played),count(d.No_ofgames) from
(
SELECT COUNT(UserGamePlayed.intID) AS 'Games_played',games.vchCompetency,b.No_Games as 'No_ofgames'
FROM UserGamePlayed
inner join games on games.intGameID=UserGamePlayed.intGameID
inner join
(
select COUNT(Games.intGameID) AS 'No_Games',vchCompetency,intGradeID from Games
WHERE intGradeID=3
GROUP BY vchCompetency,intGradeID
) as b on b.vchCompetency=games.vchCompetency
WHERE intUserID=403 and UserGamePlayed.intGradeID=3
GROUP BY games.vchCompetency,b.No_Games
)as d
the table which i get from d is:
As per the table d i want to get a count of played,when exicute a full i am getting
You should replace COUNT with SUM (in your outer select only).
COUNT only counts (as the name indicates ;)) the rows while SUM will add up the values that are passed to it.