counting in three joined table - sql

I have three tables. The first one is PrivteOwner and has 5 columns (ownerno, fname, lname, address, telno), the second one is PropertyForRent that has 10 columns (propertyno, street, city, postcode, type, rooms, rent, ownerno, staffno, branchno) and the third one is Viewing with 4 columns (clientno, propertyno, viewdate, comment).
I want to find the owner who has the most properties without a viewing. My code is as below:
SELECT
CONCAT (A.fname, ' ', A.lname) AS OwnerName,
A.ownerno, B.propertyno, B.ownerno
FROM
PrivateOwner AS A
INNER JOIN
PropertyforRent AS B ON A.ownerno = B.ownerno
LEFT JOIN
viewing AS C
SELECT
ownerno, COUNT(ownerno), viewdate
FROM
Max_Property
GROUP BY ownerno
ORDER BY COUNT(ownerno) DESC
WHERE
ROWNUM = 1 and viewdate IS NULL;
Does this code work correctly? If yes how we can write it efficiently?

It's very difficult to answer question if you don't provide data definition, data or your expected result.
Anyway, from your description I think this might get you your desired result.
SELECT
TOP 1
PrivteOwner.ownerno,
PrivteOwner.fname,
PrivteOwner.lname,
COUNT(ViewNumber) AS PropertyNumber
FROM
(
SELECT
PropertyForRent.propertyno AS propertyno
, COUNT(Viewing.propertyno) AS ViewNumber
FROM PropertyForRent
LEFT JOIN Viewing ON Viewing.propertyno = PropertyForRent.propertyno
GROUP BY PropertyForRent.propertyno
) AS NoView
JOIN PropertyForRent ON PropertyForRent.propertyno = NoView.propertyno
JOIN PrivteOwner ON PrivteOwner.ownerno = PropertyForRent.ownerno
WHERE ViewNumber = 0
GROUP BY PrivteOwner.ownerno,
PrivteOwner.fname,
PrivteOwner.lname
ORDER BY PropertyNumber DESC

Related

SQL statement is returning the top value rather than the correct value

I have these tables with practice questions that are asked, but I am running into some issues. The first question asks "Find the first name and last name of the student who has the highest GPA in CIS415 in Fall 2019."
The tables that are needed to find the correct values:
Students (SID, Firstname, Lastname, Age, Email, Phone) //SID = Student ID
Courses (CID, Name, Capacity) //CID = Course ID
Enrolls (CID, SID, Semester, GPA)
The SQL statement I have currently is:
SELECT Firstname, Lastname
FROM students
JOIN Enrolls ON student.sid = enrolls.sid
GROUP BY CID, Semester
HAVING MAX(GPA)
AND CID = 'CIS415'
AND semester = 'Fall2019';
I believe it is just pulling the students firstname and lastname from the top of the table. I am unsure of the problem and would love some input. THANK YOU.
SELECT [S].[Firstname], [S].[Lastname]
FROM Students [S]
INNER JOIN Enrolls [E]
ON [S].[SID] = [E].[SID]
INNER JOIN
(
SELECT MAX( [GPA] ) AS [GPA],
[CID] AS [CID],
[SID] AS [SID]
FROM Enrolls [E2]
GROUP BY
[CID], [SID]
) [DT]
ON [E].[CID] = [DT].[CID]
AND [E].[SID] = [DT].[SID]
WHERE
[E].[CID] = 'CIS415'
AND
[E].[semester] = 'Fall2019'
AND
[E].[GPA] >= [DT].[GPA]

how to display all columns of table

i am working on a store producer for a filter. i have many types of checks in my sp just like
if(#cityId!=0 and #sourceLatitude!=0 and #sourceLongitude!=0
and #KM!=0 and #food='' and #price='' and #sort='')
but i show just one table against all checks but i am also using group and AVG().
my question is, is there any way to display all fields without writing in group by.
my code
SELECT
--cast(AVG(rr.Rates ) as decimal(10,5)) Rating,
round(AVG(rr.Rates ),2) Rating,
[dbo].[Fun_distanceCalculate](r.Latitude,r.Longitude,#sourceLatitude,#sourceLongitude) AS Distance,
[dbo].[Fun_calculate_delivery_fee](r.Latitude,r.Longitude,#sourceLatitude,#sourceLongitude) AS DeliveryCharges,
r.Id,
r.IsActive,
r.CreatedDate,
Name,
TagLine,
ApproximateCostPerPerson,
FullAddress2,
FullAddress,
Tags,
IsRecommend,
Longitude,
DeliveryTime,
IsOnline,
Logo,
ImageUrl,
Latitude,
ProductDiscount,
TagLine,
IsApproved,
Salt,
Email,
PhoneNumber,
CityId,
CountryId
FROM [dbo].[Restaurants] r left join [dbo].[RestaurantReviews] rr
on r.Id=rr.RestaurantId
WHERE r.IsActive = 1 and r.IsApproved=1 and ((r.CityId=#cityId) OR #KM > [dbo].[Fun_distanceCalculate](r.Latitude,r.Longitude,#sourceLatitude,#sourceLongitude))
--ORDER BY Id DESC
--OFFSET #PageNumber ROWS
--FETCH NEXT #pageSize ROWS ONLY
group by r.Id,Name,
r.IsActive,
TagLine,
ApproximateCostPerPerson,
FullAddress2,
FullAddress,
IsOnline,
Tags,
Logo,
IsRecommend,
Longitude,
DeliveryTime,
ImageUrl,
Latitude,
ProductDiscount,
TagLine,
IsApproved,
Salt,
Email,
PhoneNumber,
CityId,
r.CreatedDate,
CountryId
You can move the aggregation to a CTE, then join the CTE to the main query.
WITH AvgRates
AS
(
r.Id
round(AVG(rr.Rates ),2) AS Rating,
FROM [dbo].[Restaurants] r left join [dbo].[RestaurantReviews] rr on r.Id=rr.RestaurantId
--can use the WHERE filtering here or in the final select
GROUP BY r.Id
)
SELECT
av.Rating,
--rest of your query
FROM [dbo].[Restaurants] r left join [dbo].[RestaurantReviews] rr on r.Id=rr.RestaurantId
INNER JOIN AvgRates av ON r.Id = av.Id
--rest of your WHERE filtering etc.

Count city and State from 2 different tables

I need to count the number of cities occurrences on 2 different tables. One Table is the Supplier table which has supplier_id, City and State. The second table is consumer with consumer id , City and State. My query needs to return the State, City number of supplier cities and number of consumer cities where the names match.
I have tried a couple different things like intersect and union all but cant get it My latest is below but it is Not sure what I am doing wrong
SELECT S.State
,C.City
,count(S.City) as Number_Of_Suppliers
,count(C.City) as Number_Of_Consumers
from dbo.Tb_Supplier S
left outer Join dbo.Tb_Consumer C
On S.STATE = C.STATE
AND S.City = C.City
group by S.state
,C.City
Use union all and group by:
select state, city, sum(supplier)
sum(supplier) as Number_Of_Suppliers,
sum(consumer) as Number_Of_Consumers
from ((select state, city, 1 as supplier, 0 as consumer
from dbo.Tb_Supplier s
) union all
(select state, city, 0 as supplier, 1 as consumer
from dbo.Tb_Consumer c
)
) sc
group by state, city

Selecting cities that have 10 or more students and instructors combined in SQL

I need to show the city, state, number of student residents, number of instructor residents, and total student/instructor residents in that city. The information is contained in 3 tables: ZIPCODE, STUDENT, and INSTRUCTOR.
The ZIPCODE table has the columns ZIP, CITY, and STATE.
The STUDENT table has STUDENT_ID and ZIP.
The INSTRUCTOR table has INSTRUCTOR_ID and ZIP.
I've tried a couple of inner joins, and intersects, but I keep getting a wide variety of errors. I'm still very new with SQL, and am not sure how to actually make this work, any help or advice would be greatly appreciated.
You probably want a mix of union and join for this. I doubt you want intersect. Plenty of ways to do this, here's one
SELECT
Z.city,
Z.state,
SUM(case when d.typ = 's' then 1 ELSE 0 END) as count_students,
SUM(case when d.typ = 'i' then 1 ELSE 0 END) as count_instructors,
Count(*) as count_all
FROM
(SELECT * FROM
(SELECT 's' as typ, zip FROM student)
UNION ALL
(SELECT 'I ' as typ, zip FROM Instructor)
) d
INNER JOIN
zipcode z
ON d.zip on z.zip
GROUP BY
z.city, z.state
I pull all the records out of each student and instructor table and union them to make one big list, make a column to keep track of the type, the sum does the counting, when the type is s, the case when returns a 1. The sum will sum the 1s up as a count. You thus end up with a city/state/typ combination for each row and when grouped on city and state and summed on the typ, it gives a count
Here's another way to do this:
SELECT
Z.city,
Z.state,
SUM(s.ct) as count_students,
SUM(i.ct) as count_instructors,
SUM(s.ct) + SUM(I.ct) as count_all
FROM
zipcode z
LEFT OUTER JOIN
(SELECT zip, count(*) ct FROM student GROUP BY zip) s
ON s.zip = z.zip
LEFT OUTER JOIN
(SELECT zip, count(*) as ct FROM Instructor GROUP BY zip) i
ON i.zip = z.zip
GROUP BY z.city, z.state
We group and count the students and the instructors in their own subqueries producing just a single count per zip and join these (left join) to all the zip codes. We group in a sub query to ensure that there is only ever a 1:1 relationship between zipcode and s/i. If it were 1:many the sums would beome distorted. Because multiple zips can refer to one city there is another round of grouping and summing to aggregate all the zips from one city

SQL Query: Retrieve list which matches criteria

Sorry, I couldn't think of a better heading (or anything that makes sense).
I have been trying to write a SQL query where I can retrieve the names of student who have the same level values as student Jaci Walker.
The format of the table is:
STUDENT(id, Lname, Fname, Level, Sex, DOB, Street, Suburb, City, Postcode, State)
So I know the Lname (Walker) and Fname (Jaci) and I need to find the Level of Jaci Walker and then output a list of names with the same Level.
--Find Level of Jaci Walker
SELECT S.Fname, S.Name, S.Level
FROM Student S
WHERE S.Fname="Jaci" AND S.Lname="Walker"
GROUP BY S.Fname, S.Lname, S.Level;
I have figured out how to retrieve the Level of Jaci Walker, but don't know how to apply that to another query.
Thankyou to everyone for your help,
I'm just stuck on one little bit when adding the rest of the query into it.
https://www.dropbox.com/s/3ws93pp1vk40awg/img.jpg
SELECT S.Fname, S.LName
FROM Student S, Enrollment E, CourseSection CS, Location L
WHERE S.S_id = E.S_id
AND E.C_SE_ID = CS.C_SE_id
AND L.Loc_id = CS.Loc_ID
AND S.S_Level = (SELECT S.S_Level FROM Student S WHERE S.S_Fname = "Jaci" AND S.S_Lname = "Walker")
AND CS.C_SE_id = (SELECT CS.C_SE_id FROM CourseSection CS WHERE ?)
AND L.Loc_id = (SELECT L.Blodg_code FROM Location L WHERE L.Blodg_code = "BG");
try this :
SELECT S.Fname, S.Name, S.Level
FROM Student S
WHERE S.Level =
(SELECT Level
FROM Student
WHERE Fname="Jaci" AND Lname="Walker"
)
but you got to be sure to have only 1 student called Jaci Walker ...
You can re-use your query as a subquery to find other entries with the same Level.
SELECT Fname, Name
FROM Student
WHERE Level = (
SELECT Level FROM Student S WHERE S.Fname="Jaci" AND S.Lname="Walker")
You don't need to group your result.
Try this
Select Fname,Lname from Student
where Level=(Select Level
from Student
where Fname='Jaci' AND Lname='Walker' );
Try this:
SELECT S.Fname, S.Name, S.Level FROM Student s
WHERE Level =
(SELECT TOP 1 Level FROM Student WHERE Fname = "Jaci" and Lname = "Walker")
If you don't use TOP 1, this query will fail if you have more than one "Jaci Walker" in your data.
I don't think you need group by and all for same...
Simply,
SELECT S.Fname, S.Name, S.Level FROM Student S WHERE S.LEVEL LIKE (SELECT LEVEL FROM STUDENT WHERE Fname="Jaci" AND Lname="Walker");
Are you looking for same?