Select single row or multiple rows based on condition - sql

I'm trying to identify a student's home district by joining a student's zip code to a district zip code. A given district may overlap several zip codes, so several possible home districts may appear for the student. For example, Zip code 99999 may include the Houston and Sugarland school districts. I can narrow down the home district to a single record when the student's city has the same name as the district name as for example if the student's city is Houston and the district name is Houston. In that case, I only want to retrieve the Houston district, not both Houston and Sugarland. However, if the student happened to live in Bayou with the zip code of 99999, then I'd want to retrieve both Houston and Sugarland districts since I don't have a fix on the district. I've tried several approaches but cannot come up with a solution. Here's
a primitive attempt:
Select S.Name, S.City, S.Zip, D.DistrictName
From tblStudent S
Left Join tblDistrict D on D.zip=S.zip
Where
(Case
When D.DistrictName=S.City then D.DistrictName
Else D.DistrictName
End)=D.DistrictName
Any suggestions are greatly appreciated!

You can try selecting each case separately and then making a union of the two queries.
Case 1: District Name equals City Name
Case 2: There is no District Name that is equal to the City Name
Something like this:
Select S.Name, S.City, S.Zip, D.DistrictName
From tblStudent S
Inner Join tblDistrict D on D.zip=S.zip and D.DistrictName = S.City
Union
Select S.Name, S.City, S.Zip, D.DistrictName
From tblStudent S
Inner Join tblDistrict D on D.zip=S.zip
Where not exists (
Select D2.* from tblDistrict D2
Where D2.DistrictName = S.City
And D2.zip = S.zip
)
SQL Fiddle: http://sqlfiddle.com/#!9/06d6d7/2/0

Related

improving the sql query for a dbms problem

I want to write a SQL query for the problem as defined below, my answer for the first part is as below, but I am not sure about the answer, can anyone help me? Is the answer correct, or if not, how can I improve it?
For the second part can anyone help me?
Let us consider the following relational schema about physicians and departments:
PHYSICIAN (PhysicianId, Name, Surname, Specialization, Gender, BirthDate, Department);
Let every physician be univocally identified by a code and characterized by a name, a surname, a specialization (we assume to record exactly one specializa- tion for each physician), a gender, a birth date, a department (each physician is assigned to one and only one department), and a home city.
Let every city be univocally identified by its name and characterized by the region it belongs to.
DEPARTMENT (Name, Building, Floor, Chief)
Let every department be univocally identified by a name and characterized by its location (building and floor) and chief. Let us assume that a physician can be the chief of at most one department (the department he/she belongs to). We do not exclude the possibility for two distinct departments to be located at the same floor of the same building.
BELONGS TO(City,Region)
Let us assume that a physician can be the chief of at most one department (the department he/she belongs to). We do not exclude the possibility for two distinct departments to be located at the same floor of the same building.
I want to formulate an SQL query to compute the following data (exploiting aggregate functions only if they are strictly necessary):
• the departments such that (i) all their physicians reside in the region Piemonte and (ii) at least one of them resides in the city Torino.
My answer for the fist part is as below:
for the second part, I don't know how to solve it .
create view X{
select b.city, b.region, b.department
from physician p inner join belong-to b on b.city= p.homecity
where b.region="Piemonte"
select name
from department d
where exists( select*
from X
where p.department =d.name )
I think this should work:
Select Distinct b.department
From physician p
Join belong-to b on b.city = p.homecity
Where Exists (Select 1 From belong-to b2 Where b2.city = p.homecity AND b2.region = "Piemonte")
Exists (Select 1 From belong-to b2 Where b2.city = p.homecity AND b2.city = "Torino") AND
NOT Exists (Select 1 From belong-to b2 Where b2.city = p.homecity AND b2.region <> "Piemonte") AND
I would use aggregation:
select p.department
from physician p join
belongsto b
on p.homecity = b.city
group by p.department
having sum(case when b.region <> 'Piemonte' then 1 else 0 end) = 0 and -- no Piemonte
sum(case when p.homecity = 'Torino' then 1 else 0 end) >= 1 -- at least one Torino

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

How can I write SQL Query?

I need a request that displays the name and surname of the clients with the smallest credit limit - among married women who do not live in Japan, Brazil or Italy.
Diagram:
This will Give all the people not in 'Japan', 'Brazil' or 'Italy') ,
Select C.Cust_first_name,C.Cust_Last_name from Customers C
Inner Join Countries C1
on C.Country_Id=C1.Country_Id
Where C1.Country_Name Not in('Japan', 'Brazil' or 'Italy')
and
C.Cust_Credit_Limit=(Select Min(Cust_Credit_Limit) From from Customers C)
If we Convert The Question to Code that will be the above code,
The Script would return the name and last name of person not in ('Japan', 'Brazil' or 'Italy') And has the lowest salary In the entire customer Base.
select top 1 * from Customers C
Inner Join
(
select MIn(cust_credit_limit) from Customers C1
Inner Join Countries CT on C1.Country_id = C1.Country_id
where CT.Country_Name Not in ('Japan', 'Brazil','Italy')
)
C2 on C2.cust_credit_limit = C.cust_credit_limit

Having count in SELECT clause

Find the names of cities that hosts both SALES and TRANSPORT departments
For my oracle database have this table
i.) DEPTLOC
//DEPTLOC
CITY DNAME
---------------------
NEWYORK IT
NEWYORK COMPUTER
LONDON Science
LONDON SALES
LONDON TRANSPORT
For my SQL select statement
SELECT CITY FROM DEPTLOC
WHERE
DEPTLOC.DNAME='SALES' OR DEPTLOC.DNAME='TRANSPORT'
GROUP BY
CITY
HAVING COUNT(*)=2;
the output always display
no rows selected.
My output should be
DNAME
--------
LONDON
For things like this, I try to use a simple join to the same table. First, I would have an index on the table by (City, DName).. then
select
d.City
from
deptLoc d
JOIN deptLoc d2
on d.city = d2.city
AND d2.dname = 'TRANSPORT'
where
d.dname = 'SALES'
It may look strange, but think about it. The outer portion WHERE clause only cares about cities that have ONE of the qualifiers. Why even count cities that dont even have that. So, now the join. Since you know the first qualifier on SALES is covered, re-join to the dept loc table again, but on the same city name AND the second instance is ALSO that of your 'TRANSPORT' component. You will be surprised at how fast it would be, especially on a large dataset.
can you try this :
SELECT CITY FROM DEPTLOC
WHERE
trim(DEPTLOC.DNAME)='SALES' OR trim(DEPTLOC.DNAME)='TRANSPORT'
GROUP BY
CITY
HAVING COUNT(*)=2;
I think in your data you have some different chars like space or new lines
you can check it
i think this could be a better query.
SELECT CITY
FROM DEPTLOC
WHERE
DEPTLOC.DNAME in ('SALES','TRANSPORT')
GROUP BY CITY

SQL Selecting from two tables

I have the following two tables...
I am trying to select all the cities belonging to a country using the country name, or using the country id but displaying only the city name and country name.
I am using the following statement but is not working, this is my first time doing SQL
SELECT CI.CITY_NAME, CO.COUNTRY_NAME
FROM CITY CI INNER JOIN COUNTRY CO
ON CI.CITY_ID = CO.COUNTRY_ID
WHERE CO.COUNTRY_ID = 1;
You're comparing a country id with a city id, seems like you'd really want to do;
SELECT CI.CITY_NAME, CO.COUNTRY_NAME
FROM CITY CI INNER JOIN COUNTRY CO
ON CI.COUNTRY_ID = CO.COUNTRY_ID
WHERE CO.COUNTRY_ID = 1;