SQL query to a database - sql-server

I have an exercice that I've been trying to complete for hours, but still no luck.
Question:
List the name, address e number of borrowed book's for all the clients that have more than 5 books loaned.
The schematic is on the picture below and so far I have done this query, that is missing the number of books loaned
select
Name, Address
from
borrower
where
cardno in (select cardno
from book_loans
group by cardno
having count(cardno) in (select emprestimo.emprestimo
from
(select COUNT(cardno) as emprestimo
from book_loans
group by cardno
having COUNT(cardno) >= 5) emprestimo));

Since you are learning, I'll give you pseudocode. You know about the having clause - that forms the basis for finding the clients. You apply that set of IDs (CardNo) by joining to borrower. Something like:
select <columns>
from (query to find cardnos > 5 books>) as cards
inner join Borrower as brw on ...
order by ...;
And learn the next lesson well - a resultset is not guaranteed to be ordered without an order by clause.

Related

GROUP BY or Aggregation Function error message [duplicate]

This question already has answers here:
GROUP BY / aggregate function confusion in SQL
(5 answers)
Closed 3 years ago.
I got an error -
Column 'Employee.EmpID' is invalid in the select list because it is
not contained in either an aggregate function or the GROUP BY clause.
select loc.LocationID, emp.EmpID
from Employee as emp full join Location as loc
on emp.LocationID = loc.LocationID
group by loc.LocationID
This situation fits into the answer given by Bill Karwin.
correction for above, fits into answer by ExactaBox -
select loc.LocationID, count(emp.EmpID) -- not count(*), don't want to count nulls
from Employee as emp full join Location as loc
on emp.LocationID = loc.LocationID
group by loc.LocationID
ORIGINAL QUESTION -
For the SQL query -
select *
from Employee as emp full join Location as loc
on emp.LocationID = loc.LocationID
group by (loc.LocationID)
I don't understand why I get this error. All I want to do is join the tables and then group all the employees in a particular location together.
I think I have a partial explanation for my own question. Tell me if its ok -
To group all employees that work in the same location we have to first mention the LocationID.
Then, we cannot/do not mention each employee ID next to it. Rather, we mention the total number of employees in that location, ie we should SUM() the employees working in that location. Why do we do it the latter way, i am not sure.
So, this explains the "it is not contained in either an aggregate function" part of the error.
What is the explanation for the GROUP BY clause part of the error ?
Suppose I have the following table T:
a b
--------
1 abc
1 def
1 ghi
2 jkl
2 mno
2 pqr
And I do the following query:
SELECT a, b
FROM T
GROUP BY a
The output should have two rows, one row where a=1 and a second row where a=2.
But what should the value of b show on each of these two rows? There are three possibilities in each case, and nothing in the query makes it clear which value to choose for b in each group. It's ambiguous.
This demonstrates the single-value rule, which prohibits the undefined results you get when you run a GROUP BY query, and you include any columns in the select-list that are neither part of the grouping criteria, nor appear in aggregate functions (SUM, MIN, MAX, etc.).
Fixing it might look like this:
SELECT a, MAX(b) AS x
FROM T
GROUP BY a
Now it's clear that you want the following result:
a x
--------
1 ghi
2 pqr
Your query will work in MYSQL if you set to disable ONLY_FULL_GROUP_BY server mode (and by default It is). But in this case, you are using different RDBMS. So to make your query work, add all non-aggregated columns to your GROUP BY clause, eg
SELECT col1, col2, SUM(col3) totalSUM
FROM tableName
GROUP BY col1, col2
Non-Aggregated columns means the column is not pass into aggregated functions like SUM, MAX, COUNT, etc..
Basically, what this error is saying is that if you are going to use the GROUP BY clause, then your result is going to be a relation/table with a row for each group, so in your SELECT statement you can only "select" the column that you are grouping by and use aggregate functions on that column because the other columns will not appear in the resulting table.
"All I want to do is join the tables and then group all the employees
in a particular location together."
It sounds like what you want is for the output of the SQL statement to list every employee in the company, but first all the people in the Anaheim office, then the people in the Buffalo office, then the people in the Cleveland office (A, B, C, get it, obviously I don't know what locations you have).
In that case, lose the GROUP BY statement. All you need is ORDER BY loc.LocationID

How to construct an SQL query for finding which company has the most employees?

I have the following tables and I would like to find the company which has the most workers. I am fairly new to sql and I would like some help on constructing the query. Any briefing would be appreciated on which keywords to use or how to begin with writing the query. I would like to
“Find the company that has the most workers.”
worker(worker_name, city, street)
work for(worker_name, company_name, salary)
company(company_name, city)
manages( worker_name, manage_name)
this will get you the company with the most employees in it.
select top 1 company_name,
count(*) as nbr_of_employees
from work-for
group by company_name
order by 2 desc
For more detailed answer please add sample data to your question and expected result.
how it works:
the group by company_name will group all records with the same company_name togheter. Because of that the count(*) will give you the number of records in work-for for each group. (thus all workers for each company)
the order by 2 desc will make sure that the company-name with the most employees is on top of the lists
Finally, the top 1 in the select will only return the first record in that list

Last Date Attended from 2 Tables SQL Server

I have searched the forum, and couldn't find an answer. So I apologize if this is out there. This seems simple in my mind, however, I can't seem to get the correct code.
I have 2 tables. STUDENT_TERMS_VIEW table holds STTR_STUDENT, STTR_TERM and TERMS table, holds the TERM_END_DATE. I need to find a way to select the student's last term based on MAX(TERM_END_DATE), but I get STTR_TERM duplicate rows per student. I need to get 1 row per student and their last term attended.
EDIT: Ok so both tables are linked by TERM.
View Code Here
As you can see, I am getting duplicate TERMS for the same student, even though I am pulling MAX(TERM_END_DATE)
SELECT * FROM
(SELECT STUDENT_TERMS_VIEW.STTR_STUDENT,
STUDENT_TERMS_VIEW.STTR_TERM,
TERMS.TERM_END_DATE
FROM STUDENT_TERMS_VIEW
JOIN STUDENT_TERMS_VIEW ON TERMS.TERMS_ID = STUDENT_TERMS_VIEW.STTR_TERM
ORDER BY TERMS.TERM_END_DATE DESC,STUDENT_TERMS_VIEW.STTR_STUDENT)
GROUP BY STUDENT_TERMS_VIEW.STTR_STUDENT
Your query is getting the max of the combination of (STTR_STUDENT and STTR_TERM). If you only want to get the max term of each student, you should only GROUP BY STUDENT_TERMS_VIEW.STTR_STUDENT. Try the query below.
SELECT stv.STTR_STUDENT, MAX(t.TERM_END_DATE)
FROM STUDENT_TERMS_VIEW stv
JOIN TERMS t ON t.TERMS_ID = stv.STTR_TERM
GROUP BY stv.STTR_STUDENT
If you also need to get the term, join it back to STUDENT_TERMS_VIEW and TERMS.
SELECT s.STTR_STUDENT, s.STTR_TERM, t.TERM_END_DATE
FROM (
SELECT stv.STTR_STUDENT, MAX(t.TERM_END_DATE) AS 'MaxDate'
FROM STUDENT_TERMS_VIEW stv
JOIN TERMS t ON t.TERMS_ID = stv.STTR_TERM
GROUP BY stv.STTR_STUDENT
) a
JOIN STUDENT_TERMS_VIEW s ON s.STTR_STUDENT = a.STTR_STUDENT
JOIN TERMS t ON t.TERMS_ID = s.STTR_TERM AND t.TERM_END_DATE = a.TERM_END_DATE

SQL Server - select distinct rows and sum of duplicates

I am facing 1 prob in implementing business solution. Any help would be much appreciated.
There is 1 table with 3 columns.
Table Employee
(
Id, Name, Salary
)
Values -
(1,John,10000),
(2,Rey, 15000),
(3,John,20000)
Expected Output -
It should fetch only distinct employees and for duplicate records of employee, it should fetch sum of salary.
So, output should be like this -
(1,john,30000),
(2,Rey,15000)
Please help
Check the basic sintaxis for GROUP BY
SELECT MIN(ID), Name, SUM(Salary)
FROM Employee
GROUP BY Name
The interesting part here is aggregation functions doesnt need to be at the end. As are usually show in the examples

Basic T-SQL COUNT

I'm new to T-SQL and this question is T-SQL Count 101.
I'm studying T-SQL with this site http://sqlmag.com/t-sql/t-sql-101-lesson-4 but I can't figure out Which part of coding says WHERE(column_name) to execute 'COUNT' if it makes sense? In other words, how does this COUNT know what to count? It just says COUNT everything as Reviews from MovieReview table.....
SELECT MovieName,
LEFT(REPLICATE('* ',AVG(Stars)),10)
AS 'Stars',
COUNT(*) AS 'Reviews'
FROM MovieReview
GROUP BY MovieName
HAVING COUNT(*) >= 4
ORDER BY Stars
Result:
The TABLE name is MovieReview that contains the ratings that the five employees have given to movies they’ve watched in their spare time. This table contains four columns: EmployeeID, Genre, MovieName, and Stars. The Stars field specifies the movie’s rating, where 1 star is the worst rating and 5 is the best rating.
I understand below coding because it specified WHERE. Count everything as '...' From Employee table Where salary is less than 3000.
SELECT COUNT(*)
AS 'Impoverished'
FROM Employee
WHERE Salary < 30000
I need to learn creating reports from Data Warehouse. I learned SQL but most of sites use T-SQL when creating reports, I don't know why.
Thanks in advance.
count(*) counts the number of rows that match the where clause if a where clause is given, per distinct combination of the group by columns if a group by column is given.
Except for the behavior noted in the previous sentence, count(*) ignores the values in those rows.

Resources