Group by similar number SQL (oracle sql) - sql

I would like to find the number of sales that have a similar purchase value from the following table:
sale_number | value
------------+-------
1 | 10
2 | 11
3 | 21
4 | 30
A vanilla group by statement groups by exact value:
select count(sale_number), value from table group by value
Would give:
count(sale_number) | value
------------+-------
1 | 10
1 | 11
1 | 21
1 | 30
Is it possible to group by inexact numbers with a threshold (say +/- 10%)? Giving the desired result:
count(sale_number) | value
------------+-------
2 | 10
2 | 11
1 | 21
1 | 30

You can do what you want with a correlated subquery:
select t.*,
(select count(*)
from t t2
where t2.value >= t.value * 0.9 and
t2.value <= t.value * 1.1
) as cnt
from t;

Related

Adding values from previous row into current row

I have a simple table and I want add a value from previous row into current and value of current in next row so it keeps on going until the end.
Please have a look at the following table data.
ID Value ValueIncrement
1 2 0
2 3 5 (2+3)
3 9 14 (2+3+9)
4 6 20 (2+3+9+6)
5 3 23 (2+3+9+6+3)
6 1 24 (2+3+9+6+3+1)
7 2 26 (2+3+9+6+3+1+2)
8 0 26 (2+3+9+6+3+1+2+0)
9 2 30 (2+3+9+6+3+1+2+0+2)
I am looking for a select query which can enable me to add values continuously.
You can do a window sum:
select id, value, sum(value) over (order by id) valueincrement
from mytable
order by id
Demo on SQL Server 2014 Fiddle:
id | value | valueincrement
-: | ----: | -------------:
1 | 2 | 2
2 | 3 | 5
3 | 9 | 14
4 | 6 | 20
5 | 3 | 23
6 | 1 | 24
7 | 2 | 26
8 | 0 | 26
9 | 2 | 28
You could also use a correlated sub-query if you are working with a small table (otherwise,for performance reason, you should absolutely not use this approach if you can use window-functions). I am assuming your valueincrement column starting with a 0 is a typo and not by design. Let us know if otherwise.
select *, (select sum(value) from mytable t2 where t1.id >= t2.id) as valueincrement
from mytable t1
order by id;
You can try a recursive sum
INSERT INTO #tmpPrueba
VALUES(2),(3),(9),(6),(3),(1),(2),(0),(2)
CREATE TABLE #tmpTest
(nId INT IDENTITY(1,1),
nValor INT NOT NULL)
SELECT *
FROM #tmpTest;
SELECT SUM(nValor) OVER (ORDER BY nId ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
FROM #tmpTest;

How to sum a value of a column filtering by the highest value of another column?

Having a table with this values:
Document | Version | Value
----------|---------|-----------
1900001 | 1 | 100
1900001 | 2 | 50
1900001 | 3 | 25
1900002 | 1 | 45
1900002 | 2 | 10
How can i get the sum only of the highest version of each document?
Expected value:
35
A simple method uses a correlated subquery:
select sum(value)
from t
where t.version = (select max(t2.version)
from t t2
where t2.document = t.document
);

Select all rows after sum of field reach specific number

I have table like below
ID | Name | Value
---+------+-------
1 | X | 10
2 | y | 15
3 | z | 3
4 | A | 20
5 | B | 6
I want to select all rows that comes after sum(Value) reach specific number
Examples :-
If that specific number is 11, the result set will be:
2 | y | 15
3 | z | 3
4 | A | 20
5 | B | 6
If that specific number is 25, the result set will be
3 | z | 3
4 | A | 20
5 | B | 6
If that specific number is 30, the result set will be
4 | A | 20
5 | B | 6
If that specific number is 50, the result set will be
5 | B | 6
You could use this correlated subquery approach to calculate running totals:
declare #value int
set #value = 11
;WITH CTE AS
(
SELECT t.*,
SumBefore = (SELECT SUM(Value)
FROM dbo.TableName t2
WHERE t2.ID <= t.ID)
FROM TableName t
)
SELECT CTE.*
FROM CTE
WHERE SumBefore > #value
DEMO
You can use this simple query (If you have SQL Server 2008+):
SELECT ID, Name, Value
FROM (
SELECT *
, SUM(Value) OVER (ORDER BY ID) As SumNow
FROM yourTable) t
WHERE
(SumNow > ?);
[SQL Fiddle Demo]
For older version of SQL Servers you can use this query:
SELECT ID, Name, Value
FROM yourTable t
WHERE
((SELECT SUM(Value)
FROM yourTable ti
WHERE ti.ID <= t.ID) > ?);
[SQL Fiddle Demo]

missing expression error occured in case statement

I have source table Test contains id column, target table testm consist of id , col2 . Could please assist me to get rid of this error.
test (source)
id
---
10
10
20
20
20
30
30
40
Target
testm
id col2
-- ----
10 1
10 2
20 1
20 2
20 3
30 1
30 2
40 1
The query:
select id, (case id
when 10 then select count(id) from test where id =10
when 20 then select count(id) from test where id =20
when 30 then select count(id) from test where id =30
when 40 then select count(id) from test where id =40
else 0 END ) col2 from test
throws the error:
missing expression
From looking at the desired output I guess that you want to number each occurrence of an id by groups; if this is the case using the row_number analytical function should do what you want:
select id, row_number() over (partition by id order by id) as col2
from test
order by id;
See this sample SQL Fiddle
Given you sample source data this would be the output:
| ID | COL2 |
|----|------|
| 10 | 1 |
| 10 | 2 |
| 20 | 1 |
| 20 | 2 |
| 20 | 3 |
| 30 | 1 |
| 30 | 2 |
| 40 | 1 |

postgresql - get count by value ranges

my data looks like this:
name | value
------------
a | 3.5
a | 13.5
a | 4.9
a | 11
a | 14
b | 2.5
b | 13.6
b | 5.1
b | 12
b | 13.5
I need the count grouped by value ranges:
name | 0-5 | 5-10 | 10-15
-------------------------
a | 2 | 0 | 2
b | 1 | 1 | 3
Any help is appreciated.
Thanks,
grassu
select name,
count(case when value <= 5 then 1 end) as "0-5",
count(case when value > 5 and value <= 10 then 1 end) as "5-10",
count(case when value > 10 and value <= 15 then 1 end) as "10-15"
from the_table
group by name;
With the upcoming version 9.4 this can be written a bit more readable:
select name,
count(*) filter (where amount <= 5) as "0-5",
count(*) filter (where value > 5 and value <= 10) as "5-10",
count(*) filter (where value > 10 and value <= 15) as "10-15"
from the_table
group by name;