prettify output of query - sql

i have this query and would like to indent the output and get the total from the last column.
Now it gives
person |year|dossiers
------------------------------------------------|----|--------
9210124 |1110| 166
9210124 |1111| 198
9210124 |1112| 162
9210161 |1110| 183
9210161 |1111| 210
9210161 |1112| 142
And i would like to have
person |year|dossiers
------------------------------------------------|----|--------
9210124 |1110| 166
|1111| 198
|1112| 162
9210161 |1110| 183
|1111| 210
|1112| 142
total 1061
Here the query
select
pers_nr "person",
to_char(import_dt,'YYMM') "year and month",
count(pers_nr) "dossiers"
from
rdms_3codon
where
trunc(import_dt) >= trunc(trunc(sysdate, 'Q') -1, 'Q')
and trunc(import_dt) < trunc(sysdate, 'Q')-1/(24*60*60)
group by
pers_nr,
to_char(import_dt,'YYMM')
order by
pers_nr
Could someone help me please ?

As noted in the comments, this is a client function, not a database one. For example, if you are using SQL*Plus, you can use:
break on person
break on report
compute sum label total of dossiers on report
The first line suppresses the duplicate person values; the second and third together generate the total at the bottom. SQL*Plus output formatting etc. is documented here.

Try this one. It will give you the totals at least but the rest
either can be replaced with NULLs also using RANK() for pers_id
or in the code of your application if any...
select
pers_nr "person",
to_char(import_dt,'YYMM') "year and month",
SUM(count(pers_nr)) OVER (ORDER BY year)
FROM ....
hope it helps abit

Related

SQL: Find minimal occurence of a specific value

I have trouble exactly explaining what my problem is. Let me start with what I am NOT asking: I am NOT asking for the minimal value of a column.
Assume the following table, which in one column lists names and in the other column lists guesses estimating the age of the person on the left. Multiple people are guessing so there are different guesses:
Name
AgeGuess
Max
34
Jennifer
21
Jordan
88
Max
29
Jennifer
22
Jordan
22
Jordan
36
...
...
and so on and so on. My question is: What is an SQL command that could give me a table filled by all names who were guessed the LEAST to be for example 36 (must be a specific value !). Additionally I'd like also like to know how often they were guessed 36. If nobody guessed them 36 I'd like to know that too.
In this example only Jordan was guessed to be 36. All the others were never guessed to be 36. I would expect an output like this:
Name
GuessedToBe36Count
Max
0
Jennifer
0
The table above is the result of me asking which people were guessed to be 36 the least amount of times.
My attempt was to group them by how often they were guessed 36. However if they were never rated 36, they also do not appear in the table at all, meaning I cannot just compute the minimum of the column.
If you want to get count of guessed ages by each user, group by user
SELECT name, COUNT(ageGuess) AS total, ageGuess FROM user_guess GROUP BY name, ageGuess ORDER BY name, total ASC
You will get then something similar to this:
name
total
ageGuess
Jordan
1
33
Jordan
3
65
Max
1
34
Please note that it will not return not guessed values. You can fill-in it when processing in back-end.
To have your wanted output, do it with sub-query:
SELECT name, (SELECT COUNT(ageGuess) FROM guesses g2 WHERE g2.name = g1.name AND ageGuess = 36) FROM guesses g1 GROUP BY name
Example

Including variables after filtering selecting only minimum values in SQL?

I am working with a twin dataset and would like to create a table with the Subject ID (Subject) and twin pair ID (twpair) for the twins with the lower (or one of the twins if the values are equal) lifetime total of marijuana use (MJ1a).
A portion of my table looks like this:
Subject
twpair
MJ1a
156
345
10
157
345
7
158
346
20
159
346
3
160
347
4
161
347
4
I'm hoping to create a table with only the twins that have the lower amount of marijuana use which would look like this:
Subject
twpair
MJ1a
157
345
7
159
346
3
161
347
4
This is the SQL code I have so far:
proc sql;
create table one_twin as
select twpair,min(MJ1a) as minUse, Subject
from twins_deviation
group by twpair;
Unfortunately this ends up causing all of the subjects to be remerged back in the dataset. If I don't include the Subject portion I get the correct values for twpair and MJ1a but not the Subject IDs.
How do I filter the dataset to only include those with the minimum values while also including variables of interest like Subject ID? Note that if two pairs of twins have the SAME value I would like to select one but it doesn't matter which I select. Any tips would be extremely appreciated!
This query should give you the desired result.
select a.subject,a.twpair,a.MJ1a from twins_deviation a join (select twpair,min(mj1a) as mj1a from twins_deviation group by twpair)b on a.twpair=b.twpair and a.mj1a=b.mj1a
If your DB supports analytic/window functions ,the same can be accomplished using a rank function ,solution given below.
EDIT1:to handle same values for mj1a
select subject,twpair,mj1a from(select subject,twpair,mj1a ,row_number() over(partition by twpair order by mj1a) as rnk from twins_deviation)out1 where rnk=1;
EDIT2:Updated solution 1 to include only one twin.
select min(subject) as subject,twpair,mj1a from(select a.subject as subject ,a.twpair as twpair,a.MJ1a as MJ1a from twins_deviation a join (select twpair,min(mj1a) as mj1a from twins_deviation group by twpair)b on a.twpair=b.twpair and a.mj1a=b.mj1a)out1 group by twpair,MJ1a;

View with input parameters

Let's say that I have a view with the following structure (and sample data):
Sample_Name Sample_Date Sample_ID
John 01-01-2015 453
Jacob 10-10-2016 777
Jingle 11-11-2017 888
Heimer 12-12-2018 999
Schmidt 07-07-2019 333
If someone specifies the year (i.e. '2019'), I want to return that year and the year prior to it. So the following data set would return:
Sample_Name Sample_Date Sample_ID
Heimer 12-12-2018 999
Schmidt 07-07-2019 333
Is there any way for me to create the view with input parameters (similar to a function), where the user can specify what date they are looking for? Wen the date is specified, the view should return data from that year and the year prior to it. I know with functions you can do something similar but according to my google search, this isn't possible in Oracle :(
It doesn't make sense.
A view is just a stored query. If you want to fetch certain data from it, use a where clause, e.g.
select sample_name, sample_date, sample_id
from your_view
where extract (year from sample_date) >= :par_year - 1;
(where you'd enter 2019 into :par_year, when prompted) (: might need to be replaced by &, depending on a tool you use).

Create column based on grouping other values

I have difficulties formulating my issue.
I have a view which brings these results. There's a need to add a column to the view, which will pair up round-trip flights with identical number.
Flt_No From_Airport To_Airport Dep_Date RequiredResult
124 |LCA |CDG |10/19/14 5:00 1
125 |CDG |LCA |10/19/14 10:00 1
197 |LCA |BCN |10/4/12 5:00 2
198 |BCN |LCA |10/4/12 11:00 2
501 |LCA |HER |15/8/12 12:05 3
502 |HER |LCA |15/8/12 15:15 3
I.e. flight 124 is going from Larnaca to CDG, and flight 125 is going back from CDG to Larnaca - they both have to have the same identifier.
Round-trip flights will always have following flight numbers.
I have a bunch of conditions which I won't write now.
Omitting hours is not an option, they're important.
I was thinking dense_rank() but I don't know how to create one identifier for 2 flights with different numbers, please help.
If your data is similar to the sample data posted, then the following query should give the required result:
SELECT *,
DENSE_RANK() OVER (ORDER BY CASE
WHEN From_Airport < To_Airport THEN From_Airport
ELSE To_Airport
END)
FROM mytable
Join conditions are not limited to simple equality. Assuming {Flight No, Departure, Destination} is unique on any one day, then a self join should do it:
select whatever
from flights outbound
inner join flights inbound on outbound.flt_no+1 = inbound.flt_no
and cast(outbound.dep_date, date)
= cast(inbound.dep_date, date)
and outbound.From_Airport = inbound.To_Airport
and outbound.To_Airpott = inbound.From_Ariport

Maximum Value from multiple tables

I am a high school math teacher and my school's "data specialist." I am self-taught in Microsft Exel and Access, and I have been recently learning some of the SQL query language behind my usual Access work. I am comfortable with using Access queries to tie together data from many sources, such as exam scores from one source, English proficiency from a second source, and home phone number from a third source.
Here is a situation that I do not know how to do in Microsoft Access.
My math students take the New York state examination up to 3 times a year. They need a score of 80 to be considered "college ready."
Here are 3 sample tables. Each table uses the unique primary key "StudentID." The Integrated Algebra exam has the code MXRE.
Table #1 name: JanuaryAlgebra
StudentID Course Mark
201 MXRE 90
202 MXRE 55
203 MXRE 67
204 MXRE 80
205 MXRE 78
Note: Student #201 and #204 have finished the exam and do not take it again.
Table #2 name: JuneAlgebra
StudentID Course Mark
202 MXRE 70
203 MXRE 76
205 MXRE 81
206 MXRE 86
207 MXRE 78
There are two new students to the school, #206 and #207. Students #205 and #206 have finished the exam with high scores, and the remaining three students try the exam a third time.
Table #3 name: AugustAlgebra
StudentID Course Mark
202 MXRE 72
203 MXRE 83
207 MXRE 93
How do I return a query with one line for each StudentID displaying their highest exam score after the end of the school year???
Thanks!
Jeff
I'm not as familiar with Access, but I think it supports T-SQL. If it does then you can select all the rows in one statement and get the max. Though I realized when writing this answer that it's probably easier with a sub-select
In SQL it would look something like:
SELECT StudentId, Course, Max(Mark)
FROM (
SELECT StudentId, Course, Mark FROM JanuaryAlgebra
UNION
SELECT StudentId, Course, Mark FROM JuneAlgebra
UNION
SELECT StudentId, Course, Mark FROM AugustAlgebra
) as NewTable
GROUP BY StudentId, Course
I would suggest altering the table structure:
YourTable (Student_ID,Course,Mark,Date)
Then you can simply query:
SELECT Student_ID,Course,MAX(Mark) AS Max_Mark
FROM YourTable
--WHERE Course = 'MXRE' --If you wanted only algebra results.
GROUP BY Student_ID,Course
Multiple tables of identical structure almost never makes sense.
You can however use your current format to do this by unioning together all your tables in a subquery.