Get the row with the max date value with criteria - access 2007/2010 - ms-access-2007

My main table, from which I take all the data from is "RequestTable" (I reduced it down to make it easier) in which I have:
ID_student
ID_professor
Date (and the three altogether are primary keys)
changeprofessor-note - if student wants to change the professor
then he/she should write in that field a sentence
why he/she wants to do the change
professor-reject-note - if the professor is not happy about the work of
the student, then he can choose not to mentor that
student anymore, leaving him without a mentor and the
student should choose another mentor later.
ID-seminar- after choosing a mentor the students
can choose the seminar they want to work on
changeofSeminar-note - if the student wants to change the seminar
then they need to write the reason why in here
(then the ID of the new seminar should be written in
the ID seminar field also)
IDapprove-reject - all approving or rejecting is going through this field
My initial theory was that the students could choose the mentor and the seminar in one row, but it seems too complicated now because I have no idea how to make everything work after changing mentors, declined mentoring, changing seminars and so on.
I set a more comfortable theory that all the students need to choose the mentor first. So that I could get easier the data of mentoring when needed. And I set "is null" in the query under the "ID_seminar" and "changeofseminar-note" because any changes on just the seminar part can't affect the rows where the students chosen their mentors/professors and got approved.
I implemented your code and got this:
SELECT [requesttable].ID_Student, Max([requesttable].Datum) AS MaxOfDatum, First([requesttable].ID_Profesor) AS ID_Profesor, [requesttable].ID_status_odobrenja
FROM [requesttable]
WHERE ((([requesttable].ID_Student) Not In (SELECT [ID_Student]
FROM [requesttable]
WHERE [IDapprove-reject] IS NOT NULL )))
GROUP BY [requesttable].ID_Student, [requesttable].IDapprove-reject, [requesttable].changeseminar-note, [requesttable].ID_seminar
HAVING ((([requesttable].IDapprovereject)=1) AND (([requesttable].changeseminar-note) Is Null) AND (([requesttable].Id_seminar) Is Null))
ORDER BY [requesttable].ID_Student, Max([requesttable].Datum), First([requesttable].ID_Profesor), [requesttable].IDapproved-reject;
And i get:
3 12 1
15 11 1
55 5 1
And I need:
3 6 1
15 6 1
52 5 1 - after being rejected by mentor 10,
the student choose another mentor (id 5) and got approved.
55 5 1
Old info below:
I got my query to this point and two other data are set to show only rows with null values to get this:
ID student Id professor date professor-reject-note ID accept/reject
3 12 12.11.2012 null 1
3 6 13.11.2012 null 1
52 10 12.11.2012 null 1
52 10 15.11.2012 NOT null 1
55 5 12.11.2012 null 1
I want my results to be
3 6 12.10.2013 null 1
15 6 7.1.2013 null 1
55 5 12.11.2012 null 1
Totally exclude StudentID 52 because of the professor-reject-note meaning the professor doesn't want to mentor the student anymore. Also I have a doubt about the ID accept/reject number in that option , maybe I could set it to 2 instead of 1 to make it easier. 1 means accepted, 2 would mean rejected, but if I set it to 2 and exclude the entire row I still can't get rid of the other ID 52 row. I'm a bit confused about it and have no clue how make it work.
If I set date to maxdate and Id professor to group by FIRST I almost get what I want, all the data is right except the Student ID 52 is still there - both rows.

You could use:
SELECT t.[id student],
t.[id professor],
t.DATE,
t.[professor-reject-note],
t.[id accept/reject]
FROM atable t
WHERE t.[id student] NOT IN
(SELECT [id student]
FROM atable
WHERE [professor-reject-note] IS NOT NULL)
Your field / column names could do with some work.

Related

How to get the values corresponding to another table?

I'm new to SQL and am a bit confused on how I would write a query in order to get the count of state in a different table.
Ie i have this table [student]
id
school_code
0
0123
1
2345
2
2345
And this other table [school]
school_code
name
State
0123
xxyy
New Jersey
2345
xyxy
Washington
3456
yxyx
Colarado
I want to find out how I would get this table which tells me the entries for state by checking each student and making a count of how often that state occurs, ordered by most occurrences in student table.
State
No. times occured (iterating through student)
Washington
2
New Jersey
1
SELECT school.state, count(school.state)
FROM student, school
WHERE student.school_code = school.school_code
GROUP BY school.state
ORDER BY count(school.state)`
I'm not sure whether this would be iterating through each student and counting them?
Or just natural-joinging student and school and then counting all the states
When I run this on data supplied, the numbers of times occurred is a really low number which doesn't seem right?
We can simply JOIN the two tables and COUNT the school code in the students table, with GROUP BY state:
SELECT
sc.state, COUNT(st.school_code)
FROM
school sc
JOIN student st
ON sc.school_code = st.school_code
GROUP BY sc.state;
We can try out here: db<>fiddle

Getting Unique Data Based on Two Columns and Date

I am new to SAS (and Proc SQL) and I am working this out as an exercise to improve my familiarity with SAS, but can't seem to get the correct solution.
I have resort data for two neighboring resorts that contains a guest identifier, resort identifier, when the person was admitted into the resort, and when they left. I have already sorted the data by guest identifier, admission date, and leave date. The data looks something like this:
ID Resort Admission_Date Leave_Date
1 B 15SEP2020 24SEP2020
1 A 24SEP2020 01OCT2020
1 B 25SEP2020 27SEP2020
1 B 28DEC2020 29DEC2020
2 B 07FEB2020 09FEB2020
2 A 09FEB2020 22FEB2020
3 B 26DEC2019 29DEC2019
3 B 30JAN2021 23FEB2021
3 A 23FEB2021 12MAR2021
3 B 13APR2021 16APR2021
3 B 05MAY2021 07MAY2021
My goal here is to identify those guests that went from resort A to resort B (and vice versa). I realize that some guests visited both resorts multiple times. To avoid this issue of multiple resort visits I would like to summarize the data so that we only have the first "switch" between hotels. In other words, once a guest switches from resort A to B (or from B to A) we do not care if they go back to the first resort.
Thus, the end dataset should look something like this:
ID Resort Admission_Date Leave_Date
1 B 15SEP2020 24SEP2020
1 A 24SEP2020 01OCT2020
2 B 07FEB2020 09FEB2020
2 A 09FEB2020 22FEB2020
3 B 26DEC2019 29DEC2019
3 A 23FEB2021 12MAR2021
I realize that this may have a simple solution, but I am not able to come up with it on my own at this time so any help on this is greatly appreciated!

How to mix sql consults to make conditions to another one

I've the following tables
series_trailers:
ID EPISODEID CONTENT AUTHOR
-----------------------------
1 122383 url1 Peter
2 9999 url2 Ana
3 923822 stuff Jhon
4 122384 url3 Drake
series_episodes:
ID TITLE SERIESID
--------------------------------
122383 Episode 1 23
9999 Somethingweird 87
923822 Randomtitle 52
122384 Episode 2 23
series:
ID TITLE
-------------------
23 Stranger Things
87 Seriesname
512 Sometrashseries
As you can see there are three tables: one with the series info, one with the series' episodes and another one which contains urls that redirect to the episode's trailers. I'd like to get the lastest rows from series_trailers but without repeating the series where they're from.
I've tried with SELECT DISTINCT EPISODEID FROM series_trailers ORDER BY id DESCbut there are two rows with the same episodes' series so I'll get the seriies Stranger things twice. Summing up I'd like to display the lastest series with new urls but I don't want to get duplicated series (that's what i'd get with the sql above)
EDIT: What I'm supposed to get:
Last updated series:
Stranger Things
Seriesname
Sometrashseries
What I'd get with my sql code:
Stranger Things
Seriesname
Sometrashseries
Stranger Things (again)
If I understood correctly, here is the latest trailer for the latest episodes (latest as in the highest series ID / series_trailer ID, so most likely added lastest).
WITH MostRecentTrailers
AS (
SELECT MAX(st.ID) "TRAILERID"
,s.ID "SERIESID"
,s.TITLE "SERIESTITLE"
FROM series_trailers st
JOIN series_episodes se ON se.ID = st.EPISODEID
JOIN series s ON s.ID = se.SERIESID
GROUP BY s.ID
,s.TITLE
ORDER BY s.ID DESC
)
SELECT *
FROM MostRecentTrailers mrt
JOIN series_trailers st ON st.ID = mrt.TRAILERID
Let me know if that does it for ya.
Edit: Fixed some typo mistakes.
This gives you the trailer with the highest ID for each episode. This answer is based on the assumption that the episode with the highest ID is the latest one.
select id, content from series_trailer where episode_id in
(select max(id)
from series_episodes
group by seriesid)

How can I group flight legs together into routes for counting?

I have a person's flight history and want to find their most frequent route. All flights are stored as a single row in a table, even return trips where a->b will be in one row and b->a will be in another.
I need to identify where two legs equate to a route; for example:
This person has flown 16 times in total
New York to Paris 2 times (Flight key: JFKCDG)
Paris to New York 2 times (Flight Key: CDGJFK)
New York to London 3 times (Flight Key: JFKLHR)
Currently I don't know a way to group the first two above as a 'Route' and therefore any query I write considers JFKLHR to be the most frequent route (6 times between NY and London) even though I can see from the data that this person has flown between NY and Paris a total of 10 times
Sample Table:
User ID¦Flight Key
-------------------
1 ¦JFKCDG
1 ¦JFKCDG
1 ¦CDGJFK
1 ¦CDGJFK
1 ¦JFKLHR
1 ¦JFKLHR
1 ¦JFKLHR
Expected Output
User ID¦Flight Key¦Count
------------------------
1 ¦JFKCDGJFK ¦4
Building on the clever idea in the answer by #fancyPants. You can use string functions to compare each leg of a route and patch together a full return trip.
I believe this query should work. The first part of the common table expression turns those flights that are round trips into three parts (src-dst-src) and the second part returns those that are one way (as src-dst).
with flights_cte as (
select
USERID,
case when left(flightkey,3) > right(flightkey,3)
then concat(flightkey, left(flightkey,3))
else concat(right(flightkey,3), flightkey)
end as flightkey,
count(*) count
from flights f
where exists (
select 1 from flights where right(f.flightkey,3) = left(flightKey,3)
)
group by
userid,
case
when left(flightkey,3) > right(flightkey,3)
then concat(flightkey, left(flightkey,3))
else concat(right(flightkey,3), flightkey)
end
union all
select userid, FlightKey, count(*)
from flights f
where not exists (
select 1 from flights where right(f.flightkey,3) = left(flightKey,3)
)
group by UserID, FlightKey
)
select flights_cte.userid, flights_cte.flightkey, flights_cte.count
from flights_cte
join (select userid, max(count) _max_count from flights_cte group by userid) _max
on flights_cte.UserID=_max.UserID and flights_cte.count = _max_count
A sample SQL Fiddle gives this output:
| USERID | FLIGHTKEY | COUNT |
|--------|-----------|-------|
| 1 | JFKCDGJFK | 4 |
Assuming routes are not a single row, otherwise you wouldn't be asking.. (although I would guess that the whole route is in some other table, maybe reservation-related)
Guessing the first step is to group this data by person and flights that compose a 'route'. I have an article called T-SQL: Identify bad dates in a time series where the time series can be modified to detect gaps between legs of over a day (guess) to differentiate routes. Second step would be to convert legs into route, i.e. JFK-CDG and CDG-JFK to single value JFK-CDG-JFK.
Then it would be a single query, counting the above single value route, and ORDER BY that count.
Good luck.

Is this SELECT and ORDER BY query the most efficient way I could have done it?

In my journey to learn SQL, I'm writing various queries on an old database of mine, but getting into more complex things, I want to make sure I'm not over engineering this. I have a table Agent, with different agents offering different prices for cities. Multiple agents can serve the same city, each with different prices. I wanted to run a query which would return the total cost of hiring all of the agents for any given city, ordered by the most expensive.
WITH orderedPrices AS (
SELECT SUM(agtFMPrice)
OVER (PARTITION BY agtCity)
AS IX FROM Agent)
SELECT IX
FROM orderedPrices
ORDER BY IX DESC
I found that doing it without the view returned by orderedPrices, it wouldn't order the prices (I assume because it's an aggregate function, or whatever they're called). Did I do this in the best way I could have, or could it be simplified?
Also, if you're feeling particularly bored, go ahead and give me a new assignment/query to do on this table. I could use the practice.
What you have written in English doesn't seem to quite match qhat you have written in SQL.
English:
- One record per City
- One field per record, showing the total cost of all associated agents
SQL:
- One record per Agent
- One field per record, showing the total cost of all agents in the same city
AgentID | agtCity | agtFMPrice
---------+---------+------------
1 | 1 | 10
2 | 1 | 20
3 | 2 | 30
4 | 2 | 10
5 | 2 | 25
Results of SQL version Results of English version
------------------------ ----------------------------
30 30
30 65
65
65
65
If you want the English version, I'd do this...
SELECT
agtCity,
SUM(agtFMPrice) AS IX
FROM
Agent
GROUP BY
agtCity
ORDER BY
SUM(agtFMPrice) DESC
To assist performance, the table could (should?) also have an Index on (agtCity)