SQL get count of value - sql

I have the following table. Now I want to count the amount of each value in this table.
value
count
1
1
-1
1
2
1
3
1
-1 and 1 should be seen as 1, so the output should be
value
count
1
2
2
1
3
1
Does someone know a quick fix?

Grouping by value, and making such values the absolute value so you ignore the negative sign:
SELECT
ABS(VALUE) VALUE, COUNT() COUNT
FROM
table
GROUP BY
ABS(VALUE)

Related

Create a column with Conditional Recursive SQL / based on a condition

Consider the table ordered by id with column IsSatisfied.
ID
IsSatisfied
1
0
2
1
3
0
4
0
5
1
6
0
....
...
I would like to create another column State, that initially takes value 0 and changes it between 0 and 1, only when the value of Isatisfied is equal to 1, as in the table below.
ID
IsSatisfied
State
1
0
0
2
1
1
3
0
1
4
0
1
5
1
0
6
0
0
....
...
...
I tried LAG() function or recursive CTE, but unfortunately failed.
The closest solution that I have found is Conditional Recursive SQL Select, but I was not able to convert it to suit my needs.
If I understand correctly, you want a cumulative sum of issatisfied -- and then the remainder when divided by 2:
select t.*,
( sum(issatisfied) over (order by id) % 2 ) as state
from t;

In Flink, how to convert the cumulative value into an incremental value in flink and then aggregate by some keys

How to convert the cumulative value into an incremental value in flink (some keys are considered to be a user, and then the cumulative value becomes the incremental value of two adjacent ones), and then on the basis of the incremental value (time Dimension, a key) for aggregation (sum)
For example, origin data is:
time A B value
0 1 1 1
0 2 2 2
0 1 1 4
0 2 2 3
1 1 1 5
1 2 2 6
After convert to incremental value, we got
time A B value
0 1 1 1
0 2 2 2
0 1 1 3
0 2 2 1
1 1 1 2
1 2 2 3
Then we aggregate by (time, A), got final result is
time A value
0 1 4
0 2 3
1 1 2
1 2 3
Is there a program that can do these two things at once?
One solution is to use session window or global window to convert the original table into an incremental table and store it in another place, and start another task to aggregate the results? But this will consume additional storage.
Sorry for my poor english and thanks for your advice.
There's no need to have two separate applications, or to store anything. Just let the output of the first step flow into the second step. Conceptually that's
results = input
.somehowDoTheIncrementalPart()
.thenAggregate();
or in SQL you could use a nested query, something like
SELECT ts, sum(diff) FROM (
SELECT ts, userId, diff
FROM events
MATCH_RECOGNIZE (
PARTITION BY id
ORDER BY ts
MEASURES
p2.v - p1.v AS diff, p2.id AS userId, p2.ts AS ts
AFTER MATCH SKIP TO LAST p2
PATTERN (p1 p2)
DEFINE p1 AS TRUE, p2 AS TRUE )
) GROUP BY ts, userId

SQL: Selecting rows from non unique column values once partitioned by another column

Using SQL here. Trying to select all rows where the column value is unique within that specific partition.
Have tried:
select *
from dataTable
where value in ( select value
from dataTable
group by tv_id, value
having count(*) > 1)
but it returns the full table-- i think the issue is that the values for many of tv_ids are identical and overlap.
What I have:
tv_id value
1 1
1 2
1 2
1 3
2 1
2 1
2 2
2 3
2 4
3 1
3 1
3 2
What I want:
tv_id value
1 2
1 2
2 1
2 1
3 1
3 1
I have a bunch of tv_ids and essentially, I only want the rows where the value is not unique within each tv_id.
Ex: I don't want tv_id, value: 3, 2 because it is the only combination in the data.
Thanks in advance!
Maybe something like this does the trick
Oracle Option
I include this oracle version because it enables you to understand better what are you querying.
select tv_id, value
from dataTable
where (tv_id, value) in (
select tv_id, value
from dataTable
group by tv_id, value
having count(1) > 1
)
SQL
But this is a standard sql version that will work with almost any database engine
select tv_id, value
from dataTable d1
join (
select tv_id, value
from dataTable
group by tv_id, value
having count(1) > 1
) d2
on d1.tv_id=d2.tv_id
and d1.value=d2.value
You need to query the same table twice because the group by makes a distinct in your data, so you won't retrieve duplicated rows as you show in your expected output.

How to update the value of a column after Select statement

I have following table and when I run the following query , select * from mytable , I get following result.
Column 1 Value 1
--------------------------------------
Row 1 1
Row 2 0
Row 3 1
Row 4 0
Row 5 1
Row 6 0
But I need all the values to 0, no matter if it's 1 or 0. So the representation would be something like this.
Column 1 Value 1
--------------------------------------
Row 1 0
Row 2 0
Row 3 0
Row 4 0
Row 5 0
Row 6 0
I can create a table variable and then go ahead and updte the records after inserting to it, but is there any other way?
select Column1, '0' as Value1 from mytable
UPDATE mytable SET [Value 1] = 0
Will change the value for all rows. But I have a feeling there is more to your question. Can you explain why you need the Value 1 field changed after the SELECT?
If you want all the Column 1 rows with a zero for Value 1, change your SELECT:
SELECT Column1, '0' [Value 1] FROM mytable

How to add sequence number to group of rows based on status column

I have a group of rows in order. Column "Status" has only two value 0/1. Now, I'd like to add a sequence number / group number for each 0/1 set. there can be 1 to many rows of 0's but only one 1 for each set in the end. How do I add a new column as sequence number that only increases when there is a 1.
example:
ID Status Row Group Number
1 0 1
2 0 1
3 1 1
4 0 2
5 1 2
6 0 3
7 0 3
8 0 3
9 1 3
question is how do I get the third column?
thank you.
Hmmm . . . This is a cumulative sum up to the previous row (plus 1). So, in SQL Server 2012+, you can do:
select t.*,
1 + sum(status) over (order by id) - status as rowgroupnumber
from t;