How to increment a variable inside CASE WHEN clause? - sql

I'm trying to make a new column with a variable that increments given a condition clause.
This is my query:
SELECT
[timestamp],
[load],
[timestamp] % 60 AS module,
group_by_column = CASE WHEN ([timestamp] % 60)= 0 then 1 else 0 end
FROM
table_01
And this is my return:
timestamp load module group_by_column
1432592618 24 38 0
1432592619 32 39 0
1432592620 21 40 0
1432592621 31 41 0
1432592622 28 42 0
1432592640 22 0 1
1432592641 31 1 0
1432592642 39 2 0
1432592643 33 3 0
1432592644 36 4 0
1432592649 32 9 0
1432592698 21 58 0
1432592700 25 0 1
1432592701 20 1 0
1432592702 27 2 0
1432592703 31 3 0
I need a table like this:
timestamp load module group_by_column
1432592618 24 38 0
1432592619 32 39 0
1432592620 21 40 0
1432592621 31 41 0
1432592622 28 42 0
1432592640 22 0 1
1432592641 31 1 1
1432592642 39 2 1
1432592643 33 3 1
1432592644 36 4 1
1432592649 32 9 1
1432592698 21 58 1
1432592700 25 0 2
1432592701 20 1 2
1432592702 27 2 2
1432592703 31 3 2
For Example, every time I found the condition [timestamp] % 60 = 0 is satisfied, I increment in the forth column.
I don't know if this is the best way to solve this problem, I just need an output as described below.
Thanks

In SQL Server 2012+, you would do a cumulative sum:
SELECT [timestamp], [load], [timestamp] % 60 AS module,
SUM(CASE WHEN [timestamp] % 60 = 0 THEN 1 ELSE 0 END) OVER
(ORDER BY timestamp) as group_by_column
FROM table_01;
In SQL Server 2008, I think you can get the same effect using dense_rank():
SELECT [timestamp], [load], [timestamp] % 60 AS module,
DENSE_RANK() OVER (ORDER BY [timestamp] / 60)
FROM table_01;

In case the counting integer should reflect the minutes that have passed since the first event, then the following will work:
SELECT [timestamp], [load], [timestamp] % 60 AS module,
([timestamp] / 60) - (SELECT min([timestamp]) / 60 FROM table_01) grp
FROM table_01;

Related

Cumulative sum in SQL using window function

QTY
STOCK
RNK
ID KEY
CUM SUM
40
35
1
1
35
20
35
2
1
0
15
35
3
1
0
58
35
4
1
0
18
35
5
1
0
40
35
1
2
35
20
35
2
2
0
15
35
3
2
0
CUM SUM should be MIN(QTY, STOCK-SUM(all rows in cumsum before the current row)) for every other row and for 1st row it should be MIN(QTY, STOCK-SUM(0))=> MIN(QTY,STOCK)
QTY
STOCK
RNK
ID KEY
CUM SUM
40
35
1
1
5
20
35
2
1
-10
15
35
3
1
-30
58
35
4
1
-7
18
35
5
1
-24
40
35
1
2
5
20
35
2
2
-10
15
35
3
2
-30
After, I tried I am getting the above output
SELECT sum(qty-stock) over (
partition by ID KEY
ORDER BY rnk
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) as CUM SUM
FROM TABLE
Need to get correct cumsum value using a window function in the existing table
You may use a rolling SUM() here, using SUM() as an analytic function:
SELECT *, SUM(QTY - STOCK) OVER (PARTITION BY ID_KEY ORDER BY RNK) AS CUM_SUM
FROM yourTable
ORDER BY ID_KEY, RNK;

Find duplicates on multiple columns in a SQL

I want to find the batchID who are having subjectID(0,1,2) only, pls help me, thanks in advance
I need answer BatchID=12 and BatchID=51, what can I do in sql
MyTable
uid BatchID SubjectID
6 2 0
7 2 1
8 2 2
9 2 4
10 3 0
11 3 1
12 4 5
13 4 0
14 5 5
15 6 5
17 7 0
18 7 1
19 7 2
26 12 0
27 12 1
28 12 2
29 1 0
30 1 1
31 1 4
62 45 5
63 46 0
64 46 1
65 46 4
107 49 6
108 49 2
109 49 4
110 50 1
111 50 3
116 0 1
117 0 4
118 51 0
119 51 1
120 51 2
You can use conditional aggregation for this:
select batchId
from your_table
group by batchId
having count(distinct case when subjectID in (0,1,2) then subjectID end) = 3
and count(case when subjectID not in (0,1,2) then 1 end) = 0
Explanation:
Group by batchId - Aggregate on batchId
count(distinct case when subjectID in (0,1,2) then subjectID end) - Produces 3 only if all three of them are present for this batchId
count(case when subjectID not in (0,1,2) then 1 end) - Produces 0 if there is no other subjectID except 0,1,2 assuming nulls are not allowed in the subjectId column.
You can use Row_Number()
;with cte as (
select *, RowN = row_number() over (partition by batchid order by uid) from #yourbatch where subjectid in (0,1,2)
) select distinct BatchId from cte where RowN > 1

Oracle - Group By Creating Duplicate Rows

I have a query that looks like this:
select nvl(trim(a.code), 'Blanks') as Ward, count(b.apcasekey) as UNSP, count(c.apcasekey) as GRAPH,
count(d.apcasekey) as "ANI/PIG",
(count(b.apcasekey) + count(c.apcasekey) + count(d.apcasekey)) as "TOTAL ACTIVE",
count(a.apcasekey) as "TOTAL OPEN" from (etc...)
group by a.code
order by Ward
The reason I have nvl(trim(a.code), 'Blanks') as Ward is that sometimes a.code is a blank string, sometimes it's a null.
The problem is that when I use the Group By statement, I can't use Ward or I get the error
Ward: Invalid Identifier
I can only use a.code so I get 2 rows for 'Blanks', as per below
1 Blanks 7 0 0 7 7
2 Blanks 23 1 1 25 30
3 W01 75 4 0 79 91
4 W02 62 1 0 63 72
5 W03 140 2 0 142 162
6 W04 6 1 0 7 7
7 W05 46 0 1 47 48
8 W06 322 46 1 369 425
9 W07 91 0 1 92 108
10 W08 93 2 0 95 104
11 W09 28 1 0 29 30
12 W10 25 0 0 25 28
What I need, is for the row with 'Blanks' to combined into 1 row. Little help?
Thanks.
You can not use the alias in the GROUP BY, but you can use the expression that builds the value:
GROUP BY nvl(trim(a.code), 'Blanks')

duplicate values after distinct

I try to get from 3 tables the data on specific bus number on specific time but the result not make any sense...
My script is:
SELECT
distinct b.OraReg as date_and_time,
b.IdMezzo as bus_number, b.StatoPorte as open_doors,
b.speed as speed, lc.codazultimafermata as platform_number,
n.descrnodo as platform_name
FROM
table 1 as b
INNER JOIN
table 2 lc ON lc.id = b.IdMezzo
INNER JOIN
table 3 n ON n.codaznodo = lc.codazultimafermata
WHERE
b.OraReg BETWEEN '2016-08-21 14:24:00' AND '2016-08-21 14:29:30'
AND b.IdMezzo = 17
AND lc.codazultimafermata IN ('47487', '47537')
AND lc.orainvio BETWEEN '2016-08-21 14:24:00' AND '2016-08-21 14:29:30'
ORDER BY
b.OraReg
My result got duplicated value for each row although I did it with distinct... What am I doing wrong ?
date_and_time bus_number open_doors speed platform_number
---------------------------------------------------------------
24:01.1 17 0 0 47487
24:01.1 17 0 0 47537
24:16.8 17 0 32 47487
24:16.8 17 0 32 47537
24:21.3 17 0 41 47487
24:21.3 17 0 41 47537
24:47.8 17 0 54 47487
24:47.8 17 0 54 47537
25:10.9 17 0 9 47487
25:10.9 17 0 9 47537
25:26.6 17 0 41 47487
25:26.6 17 0 41 47537
25:42.1 17 0 5 47487
25:42.1 17 0 5 47537
25:44.9 17 1 0 47487
tables structure -
table 1 -
OraReg datetime Checked
IdMezzo int Unchecked
StatoPorte tinyint Checked
speed tinyint Checked
table 2 -
dataora datetime Unchecked
codazultimafermata int Checked
table 3 -
cinnodo int Unchecked
codaznodo int Checked
descrnodo varchar(50) Checked

SQL How to group a table with special condition and join to another table

i have Table PRICE
CodePrice CodeClient TheZone Tempo W_Begin W_End Price
A_0_49 88989 1 1 0 49 20
A_50_99 60000 1 1 50 99 10
B_0_49 88989 2 1 0 49 30
C_0_49 50000 3 4 0 49 40
Table Ordre
NoID CodeClient Cp Agence TheZone Tempo Weight
01 88989 44 bidon 1 1 12
02 60000 49 toto 2 2 10
03 60000 49 bigoi 1 1 56
04 88989 49 titi 3 3 8
05 50000 44 bidon 1 1 5
How can i show the result like this:
CodePrice TheZone Tempo W_Begin W_End SUm_Weight SUM_Price CountIDOrdre CP Agence
A_0_49 1 1 0 49 17 40 2 44 bidon
A_50_99 1 1 50 99 56 10 1 49 bigoi
B_0_49 2 1 0 49 0 0 0 null null
C_0_49 3 4 0 49 0 0 0 null null
in 1 SQL Syntax (1 Step).
Nowdays i make it in 2 step
SELECT CodePrice
,CodeClient
,TheZone
,Tempo
,W_Begin
,W_End
,Price
FROM PRICE
LEFT JOIN T_TARIF_ZONE ON PRICE.ZONE = T_TARIF_ZONE.NO_ID
LEFT JOIN CLIENT ON PRICE.CodeClient= CLIENT.CODE_CL
WHERE CodeClient= #NO_CLIENT AND TheZone = #ZONE AND UNITE = #UNITE
AND (Tempo IN (SELECT ParsedString From dbo.ParseStringList(#ModLiv)))
ORDER BY MONTANT
after i select the price, now i can group the ordre on each price depends on Weight, zone, and another variable
SELECT count(NoID) as LVId
,sum(Weight)as Tot_Poids
,sum(Price) as Tot_Prix
FROM [Ordre]
WHERE Weight>= #TR_DEB AND Weight<= #TR_FIN AND LE_ZONE = #LE_ZONE AND ENLEV_UNITE = #ENLEV_UNITE
AND DATE_CLOTURE >= #Date_Deb AND DATE_CLOTURE <= #Date_Fin AND STATUT_LV = 2 AND FACTURATION = #FACTURATION
HAVING count([NOID]) > 0