SQL - Find number in a range of numbers - sql-server

SQL is not my forte, and I am not sure how to ask the question, some help would be much appreciated.
I need to extract a record that falls between a range of numbers. So I have a number e.g 230, that would return a rate of 60, based on the table below.
MinR MaxR Rate
1 3000 60.00
3001 5000 50.00
5001 7000 48.00
7001 10000 45.00
10000 999999 43.00
Logically I have tried MinR >=237 and MaxR <=237, to no avail.
Is there a simple statement to achieve this, or should I be tackling this more programatically (cursor, If..then, etc)
Many thanks
Graham

You can use BETWEEN as follows:
SELECT Rate
FROM YourTable
WHERE 230 BETWEEN MinR AND MaxR - 1
Used -1 part so that you do not get two records for one input.

You're almost there, you just have your logic backwards. Let's look at MinR >=237 and MaxR <=237 and plug in the numbers from the first row:
1 >= 237 AND 3000 <= 237
Is that condition satisfied? Obviously not: 1 is not greater or equal than 237. It works if you do it the other way around:
MinR <= 237 AND MaxR >= 237
or, to improve readability (and to avoid this kind of mistake in the future):
237 BETWEEN MinR And MaxR

Related

Iterate in ranges in Python

in Python, I need to iterate numbers in ranges like this:
0-200
201-400
401-800
801-1200
etc.
until the len() of a certain file is reached.
i.e. the first steps includes 200 elements and the further ones 199. But it would be no problem, if all of them would include 200, meaning:
0-200
201-401
402-602
603-803
The most important thing is to receive all documents behind these numbers in this ranges of approximately 200 once.
When I tried it, I was not happy with the result:
a = 0
b = 200
for i in range(a, len(files), b):
print(a,b)
print('\n')
a = a+b
b = b+b
because I get this output containing duplicates ("200" is in the first and second range) and missing ranges (e.g. 400-600):
0 200
200 400
600 800
1400 1600
etc.
or this example:
a = 0
b = 200
for i in range(a, len(files), b):
print(a,b)
print('\n')
a = a+b+1
b = b+b
also unsatisfying result:
0 200
201 400
602 800
1403 1600
etc.
There are also some unwanted jumps and for example a missing range between 400 and 600.
Does anyone have an idea how to handle this? As I said, it does not really matter, which exact range is underlying. I just need a constant one covering all numbers once.
Thank you very much!
Ok I seem to have a solution:
a = 0
b = 200
for i in range(a, len(files), b):
print('\n')
print(a, b)
a = a + 200 +1
b = b + 200 +1
delivers the output:
0 200
201 401
402 602
603 803
804 1004
Still thank you, if you've tried anything. I would keep this for possible other people handling the same problem.

How to extract a handicap value from column based on 2 criteria

Good morning,
I have an issue with extracting the correct handicap value within the following table:
K L M
Handicap York Hereford
0 1287 1280
1 1285 1275
2 1280 1271
3 1275 1268
4 1270 1265
5 1268 1260
6 1265 1258
7 1260 1254
8 1255 1250
9 1253 1246
I also have these 2 lines of sample score/round data:
G H I
Round Score Handicap
York 1269 5
York 1270 4
Hereford 1269 XXX
Hereford 1270 XXX
If for instance someone on a York, gets a score of 1269, they should get a handicap of 5, which this formula achieves:
INDEX($K$7:$K$16,MATCH($H7,$L$7:$L$16,-1))+1
However this formula only works on the one column $L$7:$L$16
Similarly, the 2ns score is calculated with the following formula:
=INDEX($K$8:$K$17,MATCH($H8,$L$8:$L$17,-1))
What I'd like to do is, build that out so if I changed the round to a Hereford, with the exact same score, the cell would automatically calculate that the handicap should be 3.
Is this possible, maybe with an array?
Regards,
Andrew.
With ms365, try:
Formula in I2:
=XLOOKUP(H2,FILTER(L$2:M$11,L$1:M$1=G2),K$2:K$11,"NB",-1,-1)
I would avoid using OFFSET because it is a volatile function.
To select the appropriate column, you can use another MATCH:
MATCH($G7,$L$6:$M$6,0)
will return the column number. This makes it simple if you more than just York and Hereford columns.
Then, to return the matching line:
=MATCH($H7,INDEX($L$7:$M$16,0,MATCH($G7,$L$6:$M$6,0)),-1)
Note the use of 0 for the Row argument in the INDEX function which will return the entire column (all the rows).
Since your handicaps are sequential, as written this formula returns the same values as does yours. But I don't think it is correct since both formulas return 1 for a 1287 York.
You probably need to subtract one from the result of the formula.
=MATCH($H7,INDEX($L$7:$M$16,0,MATCH($G7,$L$6:$M$6,0)),-1)-1
Reference your lookup range with an OFFSET() function, and for the third parameter (which is column offset), use a MATCH() on the headers.
The formula on your first row would be:
=INDEX($K$7:$K$16,MATCH(H7,OFFSET($L$7:$M$16,0,MATCH(G7,$L$6:$M$6,0)-1,ROWS($L$7:$M$16),1),-1))+1

Calculating the Custom Time with Back Tracking the record

I am trying to calculate the timing by back tracking in SQL Server but am not able to find a reliable way to do it.
The table I am using is
ID Student StudentLeader TestTime
1 132897 132897 1440
2 132555 132897 120
3 132475 132897 126
4 132659 132897 100
I am trying to calculate the timing as below
Student TimeBeforeTest TimeAfterTest
132897 1440 0
132555 120 246 = (SUM 2+3)
132475 126 226 = (SUM 3+4)
132659 100 0
Can anybody please guide me how to do it

AVG giving a Count instead of Average

This is probably a silly mistake on my end but I can't quite figure it out on my on.
I'm trying to calculate average over a set of data pulled from a sub-query presented in the following way:
TotalPDMPs DefaultClinicID
13996 -1
134 23
432 29
123 26
39 27
13 21
40 24
46 30
1 25
Now the average for each 'DefaultClinicID' calculated for 'TotalPDMPs' is the same as the data above.
Here's my query for calculating the average:
select DefaultClinicID as ClinicID, AVG(TotalPDMPs)
from
(select count(p.PatientID) as TotalPDMPs, DefaultClinicID from PatientPrescriptionRegistry ppr, Patient p
where p.PatientID = ppr.PatientID
and p.NetworkID = 2
group by DefaultClinicID) p
group by DefaultClinicID
can someone tell me what I'm doing wrong here?
Thanks.
The group by column is the same so it gets a count in the inner query by DefaultClinicID and then it tries to take an average of the same DefaultClinicID.
Does that make sense? Any aggregation on that column while you group by the same thing will return the same thing. So for clinic 23 the average calculation would be: 134 / 1 = 134.
I think you just need to do the average in your inner query and you get what you want. Or maybe avg(distinct p.patientID) is what you are after?
In the inner sub-query you already grouped by DefaultClinicID,
So every unique DefaultClinicID has already only one row.
And the avg of x is x.

NUMERIC and VARCHAR

I am using SQL Server 2008 R2 to run queries and I have come across a database where it stores numeric values as varchar(4). For example:
SELECT [num]
FROM [TABLE1]
WHERE num > '95'
I get the below results
96
97
98
99
999
However when I run the same query without the '' i.e.
SELECT [num]
FROM [TABLE1]
WHERE num > 95
then I get
100
101
102
103
104
105
106
107
108
109
110
111
112
113
116
117
120
7001
7002
7003
7004
7005
7006
7007
96
97
98
99
999
In any case, I am not getting numbers in order i.e. 95, 96, 97, 98, 99. I understand this is because they are stored as varchar(4) i.e. of a string format. Please can someone explain what happens in both situations and how does a string compare in both the above cases?
Also if someone can help me write the code to change these varchar(4) into numeric on the fly so I can arrange them properly?
Much appreciated.
When you use > '95' it compares the "numbers" in alphabetical order, that's why the result is like that. When you use > 95 it type casts the column into a number and that's why the different result.
To be sure what actually happens, you should do the casting yourself. And of course you should not store numbers as varchars.
The correct ordering would be with
order by convert(int, num)
but it will fail if there's non-numeric fields in the table.
The > does a lexicographical comparison on strings, not numbers. So the output is in order of a string (order by ASC).

Resources