homework - trying to calculate multiple flight stops between two cities? - sql

This is for a database class, using Oracle DB 11g
Tables:
• Flight (flt_no, from_city, to_city, flt_distance,
flt_departs, flt_arrives, flt_price)
• Aircraft (craft_id, craft_name, cruising_range)
• Employee (emp_id, emp_name, emp_salary)
• Certified (emp_id, craft_id)
QUERY: A customer wants to travel from Madison to New York with no more than two changes of flight. List the choice of departures from Madison if the customer wants to arrive at New York by 6pm.
ANY Help is appreciate for this. I really don't even know where to start on this.
EDIT
This is what I've come up with so far. Please let me know if I'm on the right track at least please.
SELECT F.flt_no
FROM Flight F
WHERE F.from_city = 'Madison'
AND F.to_city = 'New York'
AND DATEPART(hh, F.flt_arrives) <= 18
UNION
SELECT F.flt_no
FROM Flight F
WHERE (F.from_city = 'Madison'
AND F.to_city IN (SELECT from_city
FROM Flight F
WHERE F.to_city = 'New York')
)
OR
(F.to_city = 'New York'
AND F.from_city IN (SELECT to_city
FROM Flight F
WHERE F.from_city = 'Madison')
AND DATEPART(hh, F.flt_arrives) <= 18
)

Think of the three cases:
A direct flight.
flight with 1 stop.
a flight with two stops.
Now start stepping through the cases.
For 1. Look for flight that start and stop, you know where and you know when by, right?
For 2. Think about those two flights. Where will they start and end, what will be in common with the two flight. What's the time criteria for each flight?
For 3. Think about those 3 segments and the characteristics of each, including dependencies
Then you finally want the union of all these if all choice are to be shown.
This function: select to_char(DATE,'HH24') may help.

As #Michael Durrant has given the answer I just want to contribute the solution in SQL format.Hope this will help.Please check the Not Equal to sign.
#Direct flight
select f.no
from flights f
where f.arrives=18:00 and (f.from='madison' and f.to='NewYork')
union
# Cases for one connecting flight
select f2.no
from flights f1, flights f2
where f2.arrives=6pm and
f1.from='Madison' and f1.to<>'New York'
and f1.to=f2.from and f2.to='New York'
and f2.depart> f1.arrives
and f2.arrives<'18:00'
union
#Cases involving two connecting flights
select f3.no
from flights f1,flights f2, flights f3
where f1.from='Madison'
and f1.to=f2.from
f1.to<>'New York'
f2.to=f3.from
f2.to<>'New York'
and f3.to='New York'
and f2.depart> f1.arrives
and f3.depart> f2.arrives
and f3.arrives<'18:00'

Related

Having SQL Server choose and show one record over other

Ok, hopefully I can explain this accurately. I work in SQL Server, and I am trying to get one row from a table that will show multiple rows for the same person for various reasons.
There is a column called college_attend which will show either New or Cont for each student.
My issue: my initial query narrows down the rows I'm pulling by Academic Year, which consists of two semesters: Fall of one year, and Spring of the following to create an academic year. This is why there are two rows returned for some students.
Basically, I need to generate an accurate count of those that are "New" and those that are "Cont", but I don't want both records for the same student counted. They will have two records because they will have one for spring and one for fall (usually). So if a student is "New" in fall, they will have a "Cont" record for spring. I want the query to show ONLY the "New" record if they have both a "New' and "Cont" record, and count it (which I will do in Report Builder). The other students will basically have two records that are "Cont": one for fall, and one "Cont" for spring, and so those would be considered the continuing ones or "Cont".
Here is the basic query I have so far:
SELECT DISTINCT
people.people_id,
people.last_name,
people.first_name,
academic.college_attend AS NewORCont,
academic.academic_year,
academic.academic_term,
FROM
academic
INNER JOIN
people ON people.people_id = academic.people_id
INNER JOIN
academiccalendar acc ON acc.academic_year = academic.academic_year
AND acc.academic_term = academic.academic_term
AND acc.true_academic_year = #Academic_year
I'm not sure if this can be done with a CASE statement? I thought of a GROUP BY, but then SQL Server will want me to add all of my columns to the GROUP BY clause, and that ends up negating the purpose of the grouping in the first place.
Just a sample of what I work with for each student:
People ID
Last
First
NeworCont
12345
Soanso
Guy
New
12345
Soanso
Guy
Cont
32345
Person
Nancy
Cont
32345
Person
Nancy
Cont
55555
Smith
John
New
55555
Smith
John
Cont
---------
------
-------
----------
Hopefully this sheds some light on the duplicate record issue I mentioned.
Without sample data its awkward to visualize the problem, and without the expected results specified it's also unclear what you want as the outcome. Perhaps this will assist, it will limit the results to only those who have both 'New' and 'Cont' in a single "true academic year" but the count seems redundant as this (I imagine) will always be 2 (being 1 New term and 1 Cont term)
SELECT
people.people_id
, people.last_name
, people.first_name
, acc.true_academic_year
, count(*) AS count_of
FROM academic
INNER JOIN people ON people.people_id = academic.people_id
INNER JOIN academiccalendar acc ON acc.academic_year = academic.academic_year
AND acc.academic_term = academic.academic_term
AND acc.true_academic_year = #Academic_year
GROUP BY
people.people_id
, people.last_name
, people.first_name
, acc.true_academic_year
HAVING MAX(academic.college_attend) = 'New'
AND MIN(academic.college_attend) = 'Cont'

SQL: nested query with tuple constructor

I have some difficulties dealing with an SQL exercise for my Intro to Database course. The SQL standard we mainly use is the Oracle one (the one compatible with Apex).
I have the following SQL database (primary keys bold):
TEENAGER(SSN, Name, Surname, BirthDate, CityOfResidence, Sex)
ACTIVITY(ActivityCode, AName, Description, Category)
SUMMER-CAMP(CampCode, CampName, City)
SUBSCRIPTION-TO-ACTIVITY-IN-SUMMER-CAMP(SSN,ActivityCode, CampCode,
SubscriptionDate)
This is what the exercise asks:
"For each teenager, born before 2005, who subscribed to activities
organized by at least 5 different summer camps, show name, surname,
birth date of the teenager and the name of each summer camp to which
the teenager subscribed to all the different activities organized by
the camp."
I do not have any problem finding the SSNs of the teenagers born before 2005 and who subscribed to at least 5 camps and I am able to find the number of different activities organized by the camp. How do I manage to use this information to find the final result?
Now, this is my attempt to a solution (I added two in-line comments with "#" for clarity):
FROM TEENAGER T, SUMMER-CAMP SC, SUBSCRIPTION-TO-ACTIVITY-IN-SUMMER-CAMP STAISC
WHERE T.SSN = STAISC.SSN AND STAISC.CampCode = SC.CampCode
AND SSN IN (SELECT T.SSN #born before 2005 and at least 5 camps
FROM TEENAGER T, SUBSCRIPTION-TO-ACTIVITY-IN-SUMMER-CAMP STAISC
WHERE T.BirthDate < TO_DATE('01/01/2005', 'DD/MM/YYYY')
AND T.SSN = STAISC.SSN
GROUP BY T.SSN
HAVING COUNT(DISTINCT STAISC.CampCode) > 4)
GROUP BY STAISC.CampCode, T.SSN
HAVING (STAISC.CampCode, COUNT(DISTINCT ActivityCode)) IN (SELECT CampCode, COUNT(DISTINCT ActivityCode) #number of activities in camps
FROM SUBSCRIPTION-TO-ACTIVITY-IN-SUMMER-CAMP
GROUP BY CampCode)```
As you can see, I am using a tuple constructor in the outer-most query in a HAVING clause to try and use the information about the total number of activities organised in a camp. Am I allowed to do that and would it work? (The professor did not give us any database since in the exam we will have to write down the query without being able to run it).
Thanks in advance!
I answer to my own question since I found a correct solution:
SELECT T.SSN, SC.CampCode, T.Name, T.Surname, T.BirthDate, SC.CampName
FROM TEENAGER T, SUMMER-CAMP SC, SUBSCRIPTION-TO-ACTIVITY-IN-SUMMER-CAMP STAISC
WHERE BirthDate < TO_DATE('01/01/2005', 'DD/MM/YYYY')
AND T.SSN = STAISC.SSN AND STAISC.CampCode = SC.CampCode
AND T.SSN IN(SELECT SSN FROM SUBSCRIPTION-TO-ACTIVITY-IN-SUMMER-CAMP
GROUP BY SSN
HAVING COUNT(DISTINCT CampCode))
GROUP BY T.SSN, SC.CampCode
HAVING COUNT(DISTINCT STAISC.ActivityCode) = (SELECT COUNT(ActivityCode)
FROM SUBSCRIPTION-TO-ACTIVITY-IN-SUMMER-CAMP STAISC2
WHERE STAISC.CampCode = STAISC2.CampCode)

Complex SQL query for a large record set

I have 3 tables. Lets start by explaining the first one
tblDistance: (airport1, airport2, distance) // airport1 and airport 2 are airport codes
This table contains the distances in miles between all airports of America there are a total of 3745 airports and the distances were calculated using a nested for loop and with each loop the counter was decremented. So for the 1st airport we calculated 3744 distances. For the second we calculated 3743 distances as we have already calculated its distance in the first loop with the first airport. Now lets say the first airport was Animas Air Park(K00C) and the second aiport is Broadus Airport(K00F). The records would appear in tblDistance as
(KOOC, other3744aiports, distance)
For second airport
(K00C, K00F, distance) //This one record has been already calculated in 1st iteration of the loop
(KOOF, other3743aiports, distance)
So except for the 1st airport if we want to find all the distances for a particular airport lets say K00F we need a union query given below.
(SELECT * FROM tblDistances WHERE tblDistances.airport1 = 'K00F')
UNION ALL
(SELECT * FROM tblDistances WHERE tblDistances.airport2 = 'K00F');
I hope I have explained it clearly. Now lets come to the other 2 tables. They are called tblHave and tblNeed
tblHave: (departure, departCode, arrival, arrivalCode, flightDate)
tblNeed: (departure, departCode, arrival, arrivalCode, flightDate)
Departure is the name of the airport from which the flight will depart and the departCode(K00C, K00F) is the code of the airport and same goes for arrival and arrivalCode.
Assume that we have a flight from (departure) San Francisco Intl (KSFO) to (arrival) South Bend Rgnl (KSBN) in the tblNeed. Now comes the real problem we have to find all the flights in the tblHave that are
On the same date as the given flight and
Departure airport is (KSFO) or within 500 miles of San Francisco Intl (KSFO) using union as explined above (lets call it qryDepart) AND
Arrival airport is (KSBN) or within 500 miles of South Bend Rgnl (KSBN) using union as explined above (lets call it qryArrival)
Sample qryArrival
SELECT tblDistances.airport2 as nearBy
FROM tblDistances
WHERE tblDistances.airport1 = 'KSFO' AND (((Abs([tblDistances].[distance]))<=500))
UNION ALL SELECT tblDistances.airport1 as nearBy
FROM tblDistances
WHERE tblDistances.airport2 = 'KSFO' AND (((Abs([tblDistances].[distance]))<=500));
I cannot figure out how can I find this and also the total no.of distance commbinations for all airports is more than 7 million. The records are in Access database. What I have figure is that I find nearby departure airports and nearby arrival airports from tblDistances and then use the IN clause to find the final results
Select * from tblHave where arrivalCode IN (qryArrival) AND departCode IN (qryDepart) AND Date = #dd/mm/yyyy#;
this is not working and the union takes too much time as the no of records is very large.
You don't need to use UNION here. You can do it in one query which should cut your execution time in half at least since you won't be checking every record twice. You can use a nested iif statement to determine which field to use for nearBy, and then change your WHERE to check both fields of the record. Like this:
SELECT
iif(
tblDistances.airport = 'KSFO',
tblDistances.airport2,
iif(tblDistances.airport2 = 'KSFO',
tblDistances.airport1,
null)
) as nearBy
FROM tblDistances
WHERE
(
tblDistances.airport1 = 'KSFO'
OR tblDistances.airport2 = 'KSFO'
)
AND (((Abs([tblDistances].[distance]))<=500))
Which would be much easier to read if you used a CASE statement, but Access doesn't support CASE. The above query does the same thing as:
SELECT
CASE
WHEN tblDistances.airport1 = 'KSFO' then tblDistances.airport2
WHEN tblDistances.airport2 = 'KSFO' then tblDistances.airport1
END as nearBy
FROM tblDistances
WHERE
(
tblDistances.airport1 = 'KSFO'
OR tblDistances.airport2 = 'KSFO'
)
AND (((Abs([tblDistances].[distance]))<=500))

BIRT Report, SQL

I am new to BIRT, and I guess my question is very easy, but I can’t see how to accomplish my objective…
The task is to create a report for different courts on their requests containing different information about courts’ employees. DataSetRow[“COURT”] represents the heading of the report and it changes according to employees’ courts, usually it changes its title alphabetically, it depends on results I get and a court which requests that information. I need to make it dependent on a USER who needs the report. For this purpose I need PERSONAL_ID columns from USER_ID and HR to match and therefore DataSetRow[“COURT”] should become the same number which COURT column has. I have no idea how to define this for a USER…
Report Parameters:
DATA_FORM,
USER_ID
There are two important tables in the database:
USERS: which contains USER_ID column and PERSONAL_ID column.
And HR: The same PERSONAL_ID and C_COURT, which I need.
SELECT
H.PERSONAL_ID,
SURNAME||' '||NAME||' '||SNAME AS NAME,
DECODE_UNI (H.T_COURT, H.C_COURT) AS COURT,
DECODE_UNI (HA.T_COURT, HA.C_COURT) AS C_COURT,
TO_CHAR (TO_DATE(BIRTH_DATE, 'yyyymmdd'),'yyyy') AS BIRTH_DATE,
DECODE_UNI (HA.T_POSITION, HA.C_POSITION) AS POSITION,
DECODE_UNI (HA.T_DEPARTMENT, HA.C_DEPARTMENT) AS DEPARTMENT,
DECODE_UNI (HW.T_AWARD_TYPE, HW.C_AWARD_TYPE) AS AWARD_TYPE,
TO_CHAR (HW.AWARD_DATE, 'dd.mm.yyyy') AS AWARD_DATE,
HW.AWARD_DESC,
U.PERSONAL_ID AS PERSONAL_USER
FROM
HR H, HR_APPOINTMENT HA, HR_AWARD HW, USERS U
WHERE
H.PERSONAL_ID = HA.PERSONAL_ID
AND H.PERSONAL_ID = HW.PERSONAL_ID
AND HA.ACTIVE = 1
AND H.C_STATE = 1
AND HA.STATUS_LAST = 1
AND H.REC_DATE <= TO_DATE (?, 'dd.mm.yyyy')
AND USER_ID = ?
Thank you in advance!
It's complicated to answer without having the whole picture, but as you described the case it seems a join is missing in the query:
AND H.PERSONAL_ID=U.PERSONAL_ID

SQL query: confusing query

I have the following tables:
Flights(flight_num, source_city, dest_city)
Departures(flight_num, date, plane_type)
Passengers(passenger_id, passenger_name, passenger_address)
Bookings(passenger_id, flight_num, date, seat_number)
And I want to find the number of departures for each type of plane for all flights that leave from Burbank. (Make sure the plane¬¬_type is also part of the result.)
So far I have
SELECT D.plane_type, COUNT(*)
FROM Departures D, Flights F
WHERE F.source_city = “Burbank”
AND F.flight_num = D.flight_num
GROUP BY D.plane_type
But I am not sure how to incorporate the fact that the planes might change for the same flight number?
You can not achieve that behaviour if yours plane_type changes with no rules.