How to select value based on between Range in SQL? - sql

I need to get the Result value based on given Input from the following table.
Gender |MinAge |MaxAge | Result
-------------------------------
C 0 25 0.11
M 0 25 1.12
M 26 30 2.25
M 31 35 1.20
M 36 40 3.58
F 0 25 1.25
F 26 30 2.25
F 31 35 1.20
F 36 40 2.02
Input values 1
***************
Gender - M
Age - 28
Expected Output
---------------
2.25
Input Values 2
***************
Gender - F
Age - 32
Expected Output
----------------
1.20
I try with Between condition but unable to find solution. I'm new to SQL. Please tell me how to write query for above condition.
Thanks

select
*
from
your_table
where Gender = 'M'
and 28 between MinAge and MaxAge

Related

Aggregate result from query by quarter SQL

Lets say I have a table which holds all exports for some time back in Microsoft SQL database:
Name:
ExportTable
Columns:
id - numeric(18)
exportdate - datetime
In order to get the number of exports per week I can run the following query:
SELECT DATEPART(ISO_WEEK,[exportdate]) as 'exportdate', count(exportdate) as 'totalExports'
FROM [ExportTable]
Group By DATEPART(ISO_WEEK,[exportdate])
order by exportdate;
Returns:
exportdate totalExports
---------- ------------
27 13
28 12
29 15
30 8
31 17
32 10
33 7
34 15
35 4
36 18
37 10
38 14
39 14
40 21
41 19
Would it be possible to aggregate the week results by quarter so the output becomes something like the bellow?
UPDATE
Sorry for not being crystal clear, I would like the current result to add upp with previous result up to a new quarter.
Note week 41 contains 21+19 = 40
Week 39 contains 157 (13+12+15+8+17+10+7+15+4+18+10+14+14)
exportdate totalExports Quarter
---------- ------------ -------
27 13 3
28 25 3
29 40 3
30 48 3
31 65 3
32 75 3
33 82 3
34 97 3
35 101 3
36 119 3
37 129 3
38 143 3
39 157 3 -- Sum of 3 Quarter values.
40 21 4 -- New Quarter show current week value
41 40 4 -- (21+19)
You can use this.
SELECT
DATEPART(ISO_WEEK,[exportdate]) as 'exportdate'
, SUM( count(exportdate) ) OVER ( PARTITION BY DATEPART(QUARTER,MIN([exportdate])) ORDER BY DATEPART(ISO_WEEK,[exportdate]) ROWS UNBOUNDED PRECEDING ) as 'totalExports'
, DATEPART(QUARTER,MIN([exportdate])) [Quarter]
FROM [ExportTable]
Group By DATEPART(ISO_WEEK,[exportdate])
order by exportdate;
You could use a case statement to separate the dates into quarters.
e.g.
CASE
WHEN EXPORT_DATE BETWEEN '1' AND '4' THEN 1
WHEN Export_Date BETWEEN '5' and '9' THEN 2
ELSE 0 AS [Quarter]
END
Its just an example but you get the idea.
You could then use the alias from the case
SELECT DATEPART(ISO_WEEK,[exportdate]) as 'exportdate', count(exportdate) as 'totalExports', DATEPART(quarter,[exportdate]) as quarter FROM [ExportTable] Group By DATEPART(ISO_WEEK,[exportdate]), DATEPART(quarter,[exportdate]) order by exportdate;

How to display on a certain amount of data for a specific column

Consider the following table
Dept product name parts WO
32 aa abc 11 1234
32 aa aas 18 2213
32 bb asd 16 3424
32 aa adf 19 1255
32 cc asa 10 7567
32 aa agd 11 1233
31 ss fsf 23 3434
I have around 100 dept. in my table. What I want is that when the dept. is 32 and the product is "aa", I only want to display 30 parts or less. So in this case the total number of parts for aa is 59. So the first aa product has 11 parts and the next aa product has 18 parts so that's 29. It should now ignore all the other aa products.
Expected Output
Dept product name parts WO
32 aa abc 11 1234
32 aa aas 18 2213
32 bb asd 16 3424
32 cc asa 10 7567
31 ss fsf 23 3434
Appreciate any help provided.
Assuming WO is a primary key then use SUM window function to solve it.
SELECT yt.Dept, yt.product, yt.name, yt.parts, yt.WO
FROM yourtable yt
LEFT JOIN (
SELECT *, sum(y.parts) over (partition by y.dept order by y.parts) tsum
FROM yourtable y
WHERE y.product = 'aa'
) t ON yt.WO= t.WO
WHERE yt.dept != 32 or (yt.dept = 32 and t.tsum < 59) or (yt.dept = 32 and yt.product != 'aa')
you can use SUM() window function where you have to partition by dept and product
SELECT dept,
product,
name,
parts,
wo
FROM (SELECT *,
SUM(parts) OVER (PARTITION BY dept, product ORDER BY name) rt
FROM t
) t_rt
WHERE rt <= 30
ORDER BY dept DESC,
product,
wo
Result
dept product name parts wo
32 aa abc 11 1234
32 aa aas 18 2213
32 bb asd 16 3424
32 cc asa 10 7567
31 ss fsf 23 3434

SQL query between and equals

there are three tables, first table name is baseline which contains all beneficiaries information and one column in the name of PPI Score and the second table in the name of PPI_SCORE_TOOKUP which contains six columns as below the third table in the name of endline which contains beneficiaries end line assessment data and also one column in the name of PPI_Score, what i want is, to join some how these tables however there is no foreign key of the baseline and endline table in the PPI_SCORE_TOOKUP table there is only PPI_Score in the tables PPI_SCORE_TOOKUP, endline and endline tables, and i want to query to show some baseline data along PPI result if the values of the ppi in the basline table is between or equals to PPI_SCORE_START and PPI_SCORE_END and also it should show endline data of the same member along with the PPI Score with its six column if ppi score in the endline table is between and equals to PPI_SCORE_START and PPI_SCORE_END all in one row.
Note: i did not try any query yet since i did not have any idea how to do this, but i expect the expected result in the bottom of this question.
Tables are as follows
baseline table
ID NAME LAST_NAME DISTRICT PPI_SCORE
1 A A A 10
2 B B B 23
3 C C C 90
4 D D D 47
endline table
baseline_ID Enterprise Market PPI_SCORE
3 Bee Keeping Yes
2 Poultry No 74
1 Agriculture Yes 80
PPI_SCORE_TOOKUP table
ppi_start ppi_end national national_150 national_200 usaid
0 4 100 100 100 100
10 14 66.1 89.5 96.5 39.2
5 9 68.8 90.2 96.7 44.4
15 19 59.5 89.1 97.2 35.2
20 24 51.3 85.5 96.4 28.8
25 29 43.5 81.1 93.2 20
30 34 31.9 74.5 90.4 13.6
35 39 24.6 66.9 87.3 7.9
40 44 15.2 58 82.8 4.5
45 49 11.4 47.9 73.4 4.2
50 54 6 37.2 68.4 2.6
55 59 2.7 26.1 61.3 0.5
60 64 0.9 21 50.4 0.5
65 69 0 14.3 37.1 0
70 74 3 14.3 29.2 0
75 79 0 1.4 5.1 0
80 84 0 0 9.5 0
85 89 0 0 15.2 0
90 94 0 0 0 0
95 100 0 0 0 0
Expected Result
Your query can be made in the following way:
SELECT *
FROM baseline b
LEFT JOIN endline e ON b.id = e.baseline_ID
LEFT JOIN PPI_SCORE_TOOKUP ppi ON b.PPI_SCORE BETWEEN ppi.ppi_start AND ppi.ppi_end
LEFT JOIN PPI_SCORE_TOOKUP ppi2 ON e.PPI_SCORE BETWEEN ppi2.ppi_start AND ppi2.ppi_end
This matches your id's from the baseline table with the baseline_ID's from the endline table, keeping possible null values from baseline. It then matches the PPI_SCORE from baseline with ppi_start and ppi_end from PPI_SCORE_TOOKUP. Then we join the PPI_SCORE from endline with and ppi_end.
By replacing * with whatever fields you want to have.
See fiddle for a working example

Oracle - Group By Creating Duplicate Rows

I have a query that looks like this:
select nvl(trim(a.code), 'Blanks') as Ward, count(b.apcasekey) as UNSP, count(c.apcasekey) as GRAPH,
count(d.apcasekey) as "ANI/PIG",
(count(b.apcasekey) + count(c.apcasekey) + count(d.apcasekey)) as "TOTAL ACTIVE",
count(a.apcasekey) as "TOTAL OPEN" from (etc...)
group by a.code
order by Ward
The reason I have nvl(trim(a.code), 'Blanks') as Ward is that sometimes a.code is a blank string, sometimes it's a null.
The problem is that when I use the Group By statement, I can't use Ward or I get the error
Ward: Invalid Identifier
I can only use a.code so I get 2 rows for 'Blanks', as per below
1 Blanks 7 0 0 7 7
2 Blanks 23 1 1 25 30
3 W01 75 4 0 79 91
4 W02 62 1 0 63 72
5 W03 140 2 0 142 162
6 W04 6 1 0 7 7
7 W05 46 0 1 47 48
8 W06 322 46 1 369 425
9 W07 91 0 1 92 108
10 W08 93 2 0 95 104
11 W09 28 1 0 29 30
12 W10 25 0 0 25 28
What I need, is for the row with 'Blanks' to combined into 1 row. Little help?
Thanks.
You can not use the alias in the GROUP BY, but you can use the expression that builds the value:
GROUP BY nvl(trim(a.code), 'Blanks')

how to get the unique records with min and max for each user

I have the following table:
id gender age highest weight lowest weight abc
a f 30 90 70 1.3
a f 30 90 65 null
a f 30 null null 1.3
b m 40 100 86 2.5
b m 40 null 80 2.5
c f 50 105 95 6.4
I need this result in sql server. What I need is the minimum of the weight and maximum of the weight and one record per user.
id gender age highest weight lowest weight abc
a f 30 90 65 1.3
b m 40 100 80 2.5
c f 50 105 95 6.4
Just do a grouping:
select id,
max(gender),
max(age),
max([highest weight]),
min([lowest weight]),
max(abc)
from SomeTable
group by id
You can do this using grouping:
select id, gender, max(highest_weight), min(lowwest_weight) from student
group by id, gender
But you need do define the rule for the other fields with variable value, like abc
Can you post more information?