How can I increment counter when the value in another column changes? - sql

I have the following table
ID
12
12
25
25
78
78
78
And I need to be able to increment the counter value when the ID changes.
ID **COUNTER**
12 1
12 1
25 2
25 2
78 3
78 3
78 3
How can this be done? Is it even possible?

You can use dense_rank():
select id,
dense_rank() over(order by id) Counter
from yourtable
See SQL Fiddle with Demo
Result:
| ID | COUNTER |
----------------
| 12 | 1 |
| 12 | 1 |
| 25 | 2 |
| 25 | 2 |
| 78 | 3 |
| 78 | 3 |
| 78 | 3 |

Related

Display Rows if Column Value is repeated

I have a SQL table that looks like this:
DATA | TEST_ID | PARAM_ID
-------------------------------------
c:\desktop\image1| 11 | 1
c:\desktop\image2| 12 | 1
c:\desktop\image3| 13 | 1
c:\desktop\image4| 14 | 1
Fail | 14 | 2
0.45 | 14 | 3
c:\desktop\image5| 15 | 1
Fail | 15 | 2
0.68 | 15 | 3
c:\desktop\image6| 16 | 1
Fail | 16 | 2
0.25 | 16 | 3
I would like to create a query where the result only shows DATA if TEST_ID has the same value repeated 3 times.
Ideal Result:
DATA | TEST_ID | PARAM_ID
-------------------------------------
c:\desktop\image4| 14 | 1
Fail | 14 | 2
0.45 | 14 | 3
c:\desktop\image5| 15 | 1
Fail | 15 | 2
0.68 | 15 | 3
c:\desktop\image6| 16 | 1
Fail | 16 | 2
0.25 | 16 | 3
Would the best approach be to use COUNT(*)>2 for the TEST_ID column?
Use window functions:
select t.*
from (select t.*, count(*) over (partition by test_id) as cnt
from t
) t
where cnt >= 3;

Reset sum when condition is met in Oracle

My data is structured as follows:
Timestamp | Hour | Count
--------------------------
20190801 01 | 1 | 10
20190801 02 | 2 | 20
20190801 03 | 3 | 10
20190801 04 | 4 | 5
20190801 05 | 5 | 15
20190801 06 | 6 | 10
20190802 01 | 1 | 5
20190802 02 | 2 | 20
20190802 03 | 3 | 5
20190802 04 | 4 | 15
20190802 05 | 5 | 20
20190802 06 | 6 | 5
20190803 01 | 1 | 30
I'm trying to make an SQL query that will calculate a running SUM but resets when the hour is 3. The result should look like this:
Hour | Count | SUM
------------------
1 | 10 | 10
2 | 20 | 30
3 | 10 | 10 /* RESET */
4 | 5 | 15
5 | 15 | 30
6 | 10 | 40
1 | 5 | 45
2 | 20 | 65
3 | 5 | 5 /* RESET */
4 | 15 | 20
5 | 20 | 40
6 | 5 | 45
1 | 30 | 75
You could create subgroup using conditional sum:
WITH cte AS (
SELECT t.*,SUM(CASE WHEN hour=3 THEN 1 ELSE 0 END) OVER(ORDER BY timestamp) grp
FROM t
)
SELECT cte.*, SUM(Count) OVER(PARTITION BY grp ORDER BY timestamp) AS total
FROM cte

PostgreSQL calculate rolling average with group and order

I have a table as follows
id | x | y | value
------+--------+-------+------------
1 | 1 | 1 | 25
1 | 1 | 2 | 42
1 | 2 | 3 | 98
1 | 2 | 4 | 54
1 | 3 | 5 | 67
2 | 1 | 1 | 78
2 | 1 | 2 | 45
2 | 2 | 3 | 96
I have to group this by id while maintaining the order by id, x, and y (in the respective order) and calculate the rolling average for previous n number of rows. For example if n = 3
id | x | y | value | rollingAvg
------+--------+-------+--------+-----------
1 | 1 | 1 | 25 | 25
1 | 1 | 2 | 42 | (25 / 1) = 25
1 | 2 | 3 | 98 | (25+42/2) = 33.5
1 | 2 | 4 | 54 | (25+42+98 /3) = 55
1 | 3 | 5 | 67 | (42+98+54 /3) = 64.67
2 | 1 | 1 | 78 | 78
2 | 1 | 2 | 45 | (78/1) = 78
2 | 2 | 3 | 96 | (78+45 / 2) = 61.5
Logic is
1) If the row is the 1st when grouped by id, the value should be the average
2) The average should not include the current row
Thanks in advance
We can use the AVG() function with a window frame to cover the previous three rows only:
select
id,
x,
y,
coalesce(avg(value) over
(partition by id order by y rows between 3 preceding AND 1 preceding), value) as rollingAvg
from your_table
order by id, y;
Demo
The call to COALESCE() is necessary, because you seem to expect that if the previous three rows are all NULL (which happens for the first record in each id group), then the current row's value should be used.

delete duplicate rows from my table

i need to delete all duplicate rows in my table - but leave only one row
MyTbl
====
Code | ID | Place | Qty | User
========================================
1 | 22 | 44 | 34 | 333
2 | 22 | 44 | 34 | 333
3 | 22 | 55 | 34 | 333
4 | 22 | 44 | 34 | 666
5 | 33 | 77 | 12 | 999
6 | 44 | 11 | 87 | 333
7 | 33 | 77 | 12 | 999
i need to see this:
Code | ID | Place | Qty | User
=======================================
1 | 22 | 44 | 34 | 333
3 | 22 | 55 | 34 | 333
4 | 22 | 44 | 34 | 666
5 | 33 | 77 | 12 | 999
6 | 44 | 11 | 87 | 333
In most databases, the fastest way to do this is:
select distinct t.*
into saved
from mytbl;
delete from mytbl;
insert into mytbl
select *
from saved;
The above syntax should work in Access. Other databases would use truncate table instead of delete.
Try this,
WITH CTEMyTbl (A,duplicateRecCount)
AS
(
SELECT id,ROW_NUMBER() OVER(PARTITION by id,place,qty,us ORDER BY id)
AS duplicateRecCount
FROM MyTbl
)
DELETE FROM CTEMyTbl
WHERE duplicateRecCount > 1

SQL count occurrences of a value

I am trying to count the occurrences of a value in SQL
id | my_id | field_number | field_id | value
------------------------------------------------------------
1 | 101 | 78 | 88 | apple
2 | 287 | 76 | 55 | orange
3 | 893 | 45 | 33 | orange
4 | 922 | 23 | 33 | grape
5 | 198 | 09 | 88 | raisin
6 | 082 | 55 | 88 | apple
If I use the following then it correctly tells me that there are 3 field_id's with the value of 88.....
$count = $wpdb->get_results("SELECT COUNT(*) as count FROM wp_db1 WHERE field_id=88");
But if I try and do this:
$count = $wpdb->get_results("SELECT COUNT(*) as count FROM wp_db1 WHERE value=apple");
Then it does not work. Can anyone help?
You missed the quotes around apple:
$count = $wpdb->get_results('SELECT COUNT(*) as count FROM wp_db1 WHERE value="apple"');