SQL: Checking if a number within range of multiple ranges - sql

Lets say we have 2 tables.
Table Values
Id Group Value
--------------------
A X 15
B Y 55
Table Ranges
Group LowLimit HighLimit
--------------------------------
X 0 10
X 20 30
Y 30 40
Y 50 60
I would like to check which Values.Id has value that falls outside the LowLimit and HighLimit of the group it belongs to in Ranges (notice each group has multiple ranges).
The desired result would be
Table Result
Id
--------------
A (because the value 15 is outside the range of both (0..10) and (20..30)
while B is not part of the result because it is within the range of (50..60) even though it is outside the range of (30..40))
What would the sql would be like?

One option uses an exists query:
SELECT
v.ID
FROM [Values] v
WHERE NOT EXISTS (SELECT 1 FROM [Ranges] r
WHERE v.[Group] = r.[Group] AND
v.[Value] BETWEEN r.[LowLimit] AND r.[HighLimit]);
Demo
In plain English, this will check each ID row from Values and check it there does not exist even one range which contains the value. If no such range exists, then this non matching ID would be reported.

Related

Extract only variables which is greater than other table in influxDB

I am using influxDB and I would like to extract some values which is greater than certain threshold in other table.
For example, I have two tables as shown in below.
Table A
Time value
1 15
2 25
3 9
4 22
Table B
Time threshold
1 16
2 12
3 13
4 15
Give above two tables, I would like to extract three values which is greater than first row in Table B. Therefore what I want to have is as below.
Time value
2 25
4 22
I tried it using below sql query, but it didn't give any correct result.
select * from data1 where value > (select spec from spec1 limit1);
Look forward to your feedback.
Thanks.
Integrate the condition in an inner join:
select * from tableA as a
inner join tableB as b on a.id=b.id and a.value > b.threshold
When your time column doesn't only include integer values, you have to format the time and join on a time range. Here is an example:
SQL join on time range

Return 0 in Sheets Query if there is no data

I need some advice in google query language.
I want to count rows depending on date and a condition. But if the condition is not met, it should return 0.
What I'm trying to achieve:
Date Starts
05.09.2018 0
06.09.2018 3
07.09.2018 0
What I get:
Date Starts
06.09.2018 3
The query looks like =Query(Test!$A2:P; "select P, count(B) where (B contains 'starts') group by P label count(B) 'Starts'")
P contains ascending datevalues and B an event (like start in this case).
How can I force output a 0 for the dates with no entry containing "start"?
The main point is to get all needed data in one table in ascending order. But this is only working, if every day has an entry. If there is no entry for a day, the results for "start" do not match the datevalue in column A. 3 in column D would be in the first row of the table then.
I need it like this:
A B C D
Date Logins Sessions Starts
05.09.2018 1 2 0
06.09.2018 3 4 3
07.09.2018 4 5 0
Maybe this is easy to fix, but I don't see it.
Thanks in advance!
You can do some pre-processing before the query. Ex: check if column B contains 'start' with regexmatch and use a double unary (--) to force the boolean values into 1's and 0's. The use query to sum.
=Query(Arrayformula({--regexmatch(Test!$B2:B; "start")\ Test!$A2:P}); "select Col17, sum(Col1) where Col17 is not null group by Col17 label sum(Col1) 'Starts'")
Change ranges to suit.

SQL complex grouping "in column"

I have a table with 3 columns (sorted by the first two):
letter
number (sorted for each letter)
difference between current number and previous number of the same letter
I'd like to calculate (with vanlla SQL) a fourth new column RESULT to group these data when the third column (difference of number between contiguos record; i.e #2 --> 4 = 5-1) is greater than 30 marking all the records of this interval with letter-number of the first record (i.e A1 for #1,#2,#3).
Since the difference between contiguos numbers makes sense just for records with the same letter, for the first record of a new letter, the value of differnce is 31 (meaning that it's a new group; i.e. #6).
Here is what I'd like to get as result:
# Letter Number Difference RESULT (new column)
1 A 1 1 A1
2 A 5 4 A1
3 A 7 2 A1
4 A 40 33 A40 (*)
5 A 43 3 A40
6 B 1 31 B1 (*)
7 B 25 24 B1
8 B 27 2 B1
9 B 70 43 B70 (*)
10 B 75 5 B70
Now I can only find the "breaking values" (*) with this query where they get a value of 1:
select letter
,number
,cast(difference/30 as int) break
from table
where cast(difference/30 as int) = 1
Even though I'm able to find these breaking values I can't finish my task.
Can anyone help me finding a way to obtain the column RESULT?
Thanks in advance
FF
As I understand you need to construct the last result column. You can use concat to do that:
SELECT letter
,number
,concat(letter, cast(difference/30 as int)) result
FROM table
HAVING result = 'A1'
after some exercise and a little help from a friend of mine, I've found a possible solution to my sql prolblem.
The only requirment for the solution is that my first record must have a value of 31 in Difference field (since I need "breaks" when Difference > 30 than the previous record).
Here is the query to get the column RESULT I needed:
select alls.letter
,alls.number
,ints.letter||ints.number as result
from competition.lag alls
,(select letter
,number
,difference
,result
from (select letter
,number
,difference
,case when difference>30 then 1 else 2 end as result
from competition.lag
) temp
where result = 1
) ints
where ints.letter=alls.letter
and alls.number>=ints.number
and alls.number-30<=ints.number

SQL - How to returns values outside a date range query

Hoping someone can help out here, I have the following data
Field 1 Field 2 Date Data
1 1 12/09/14 1
2 2 12/09/14 1
3 1 11/09/14 1
4 3 11/09/14 1
I need to write an sql query that sums all "Data" based on a date range and then anything that matches in Field 2. So if a line is out of the date range but the value in Field 2 matches another line that is within the date range, it should be included
For example, if I was to query everything for the 12/09/14, I want to see the sum of line 1, 2 and 3.... as line 3 is outside of the date range but it matches line 1 in the "Field 2" column. Line 4 should not be included as it is outside the range and does not have a matching value in "Field 2"
Any ideas?
I've been playing around with variations of queries but it either selects only the date range values or everything :(
EDIT:
Ok I've given Rajesh answer a try and it doesn't seem to include the data outside the date range. I was expecting the final sum in this example to equal 3 but it's only showing 2
select sum(a) from (
select sum(batch_m2_nett) as a
from batch_inf
where batch_date = to_date('30/09/15','DD/MM/RR')
union
select sum(f2.batch_m2_nett) as a
from batch_inf f1
inner join batch_inf f2
on f1.batch_date = to_date('30/09/15','DD/MM/RR')
and f1.batch_opt_start_batch = f2.batch_opt_start_batch
and f2.batch_date != to_date('30/09/15','DD/MM/RR')
);
SUM(A)
------
2
SQL> select batch_no, batch_opt_start_batch, batch_date, batch_m2_nett from batch_inf where batch_no in (8811,8812,8814);
BATCH_NO BATCH_OPT_START_BATCH BATCH_DATE BATCH_M2_NETT
-------- --------------------- --------------- -------------
8811 8814 30-SEP-15 1
8812 8814 30-SEP-15 1
8814 8814 01-OCT-15 1
the first statement gets sum of data values where date matches
the second statement gets sum of data values where field2 of matched date row is matching with other rows using self join
select SUM(s)
from
(
select SUM(data) as s
from fields
where date ='12/09/14'
union
select sum(f2.data) as s
from fields f1
inner join fields f2
on f1.date ='12/09/14'
and f1.field2 = f2.field2
and f2.date != '12/09/14'
) T

Retrieve Duplicate Row value and Count

I have table named "Table X" which contains some names and their corresponding age, table may contains same names (i.e) names will occur repeatedly.
Table x:
name age
a 21
b 37
c 23
a 34
a 21
b 19
b 37
a 21
...output like the One Below:
name total repeat
a 4 2
b 3 1
c 1 0
Now I want to write a query which will return total # of repeated names, and how many times the age repetitions occur in the resulting table. Just like the output table given above.I want to do it with MS Access.
try this
SELECT x.pname, SUM(x.CountOfpage) as Total, SUM(x.CountOfpage-1) as Repeats
FROM (
SELECT TableX.pname, TableX.page, Count(TableX.page) AS CountOfpage
FROM TableX
GROUP BY TableX.pname, TableX.page
) as x
GROUP BY x.pname