Counting Using Duplicate Column - sql

I have a table below.
ClientID | FileCount | LinkNumber | ActualFileCount |
----------|-----------|------------|-----------------|
1 | 1 | 0 | 1 |
----------|-----------|------------|-----------------|
2 | 1 | 0 | 1 |
----------|-----------|------------|-----------------|
3 | 2 | 0 | 2 |
----------|-----------|------------|-----------------|
4 | 1 | 123 | 1 |
----------|-----------|------------|-----------------|
5 | 1 | 123 | 0 |
----------|-----------|------------|-----------------|
6 | 2 | 456 | 2 |
----------|-----------|------------|-----------------|
7 | 2 | 456 | 0 |
----------|-----------|------------|-----------------|
8 | 2 | 456 | 0 |
----------|-----------|------------|-----------------|
9 | 1 | 789 | 1 |
----------|-----------|------------|-----------------|
10 | 1 | 789 | 0 |
Basically if the LinkNumber is 0 then copy the FileCount column into ActualFileCount column. However, if the LinkNumber is not 0 then the ActualFileCount must be only a single value related to that LinkNumber.
For example ClientID 4 and 5, they are husband and wife, so we link them both. The system give them each FileCount 1. However, since they are link, there is only 1 ActualFileCount for both (only 1 'physical' file for both).
I use the syntax below I excel (using an example for ClientID 3 and ClientId 4)
If (LinkNumber = 0 then FileCount else
(If (LinkNumber for ClientID 4 = LinkNumber for ClientID 3 then 0 else FileCount)
When I translate it to SQL Server 2012, it doesn't work.
select ClientID, file_count, LinkNumber,
If LinkNumber = 0 then file_count
else If LinkNumber + 1 = LinkNumber Then 0 else FileCount
end
as ActualFileCount
from TableA
order by LinkNumber asc
Thanks guys for your help.

SELECT clientid,
filecount,
linknumber,
CASE WHEN linknumber = 0 OR rnum = 1
THEN filecount
ELSE 0
END actualfilecount
FROM (SELECT *,
ROW_NUMBER() OVER (PARTITION BY linknumber ORDER BY clientid) rnum
FROM t_client
) t
Result
clientid filecount linknumber actualfilecount
1 1 0 1
2 1 0 1
3 2 0 2
4 1 123 1
5 1 123 0
6 2 456 2
7 2 456 0
8 2 456 0
9 1 789 1
10 1 789 0
WITH result of ROW_NUMBER()
clientid filecount linknumber actualfilecount rnum
1 1 0 1 1
2 1 0 1 2
3 2 0 2 3
4 1 123 1 1
5 1 123 0 2
6 2 456 2 1
7 2 456 0 2
8 2 456 0 3
9 1 789 1 1
10 1 789 0 2

Related

Update column according max value from other column SQL [duplicate]

This question already has an answer here:
SQL Set column with Key and max value from other colum
(1 answer)
Closed 1 year ago.
Taking the max value of column 'time', I need update the column 'register' group by Identification column, set register = 1 and the rest register = 0
Initial table:
Identification | time | register
1 | 0 | 0
1 | 7 | 0
1 | 3 | 0
2 | 10 | 0
2 | 5 | 0
2 | 0 | 0
3 | 6 | 0
3 | 5 | 0
3 | 0 | 0
Ending table:
Identification | time | register
1 | 0 | 0
1 | 7 | 1
1 | 3 | 0
2 | 10 | 1
2 | 5 | 0
2 | 0 | 0
3 | 6 | 1
3 | 5 | 0
3 | 0 | 0
In SQL 2017, the table contains thousand of registers
Seems like you want a CASE expression and a windowed MAX:
SELECT Identification,
[time],
CASE [time] WHEN MAX([time]) OVER (PARTITION BY Identification) THEN 1 ELSE 0 END AS register
FROM dbo.YourTable;

Sql Query that returns columns with counts based on grouped values from one table

I have a table of Tasks. There may be many tasks with various statuses to one Activity. I need to add columns to the main Activity view that displays the count of how many open tasks, closed tasks and total tasks. I thought I would create a view with the totals grouped per Activity then join via the ActivityID. I am having trouble creating the view with the correct figures, please help.This doesn't return the correct numbers:
The status values that equate to an 'OpenTasks' is 0,1 & 3. 'ClosedTasks' is 3
Existing table - Tasks
ID | WorkID| Status
1 | 5 | 2
2 | 5 | 2
3 | 5 | 0
4 | 5 | 3
5 | 6 | 2
6 | 7 | 0
7 | 7 | 0
8 | 9 | 1
9 | 9 | 2
The resulting view I require is:
WorkID | OpenTasks | ClosedTasks | TotalTasks
5 | 2 | 2 | 4
6 | 0 | 1 | 1
7 | 2 | 0 | 2
9 | 1 | 1 | 2
SELECT top 10000 WorkActivityId,
COUNT(CASE WHEN status = 2 then 1 ELSE NULL END) as "ClosedTasks",
COUNT(CASE WHEN status <> 2 then 1 ELSE NULL END) as "OpenTasks",
COUNT(CASE WHEN status < 10 then 1 ELSE NULL END) as "TotalTasks"
FROM [SDMTWorkActivity].[WorkActivity].[Tasks]
GROUP BY WorkActivityId order by WorkActivityId
I am not great as SQL so appreciate any advice Thank you
Your query should be working but you can try the following using sum
SELECT
WorkId,
SUM(CASE WHEN status <> 2 then 1 ELSE 0 END) as "OpenTasks",
SUM(CASE WHEN status = 2 then 1 ELSE 0 END) as "ClosedTasks",
SUM(CASE WHEN status < 10 then 1 ELSE 0 END) as "TotalTasks"
FROM [SDMTWorkActivity].[WorkActivity].[Tasks]
GROUP BY WorkId
order by WorkId
output:
| WorkId | OpenTasks | ClosedTasks | TotalTasks |
| ------ | --------- | ----------- | ---------- |
| 5 | 2 | 2 | 4 |
| 6 | 0 | 1 | 1 |
| 7 | 2 | 0 | 2 |
| 9 | 1 | 1 | 2 |

Oracle SQL - Running Sum based on group by and condition

I have table that looks like
ID SEQ LABEL COUNT
1 1 0 3
1 2 0 2
1 3 0 6
1 4 1 2
1 5 0 3
1 6 0 5
2 1 0 2
2 2 1 1
2 3 0 3
I would like to create a column called running_count. It calculates cumulative sum of the column count till the Label is 1 and then reset and start cumulative sum again.
Expected Output:
ID SEQ LABEL1 COUNT1 RUNNING_COUNT
1 1 0 3 3
1 2 0 2 5
1 3 0 6 14
1 4 1 2 16
1 5 0 3 3
1 6 0 5 8
2 1 0 2 2
2 2 1 1 3
2 3 0 3 3
I tried the following query
SELECT A.*, SUM(COUNT1) over (partition by ID,LABEL1 order by SEQ) as RUNNING_COUNT FROM TABLE_1 A
The problem here is that the cumulative sum stops in previous row(Seq) for Label = 1. I need to get the running sum till Label = 1 for Each ID based on Seq.
The Wrong Output I am getting
ID SEQ LABEL1 COUNT1 RUNNING_COUNT
1 1 0 3 3
1 2 0 2 5
1 3 0 6 14
1 4 1 2 2
1 5 0 3 3
1 6 0 5 8
2 1 0 2 2
2 2 1 1 1
2 3 0 3 3
You could make a first window sum() to define the groups, then use it as partition for the outer query:
select
t.*,
sum(count1) over(partition by id, grp order by seq) running_count
from (
select
t.*,
sum(label) over(partition by id order by seq desc) grp
from mytable t
) t
Demo on DB Fiddle:
ID | SEQ | LABEL | COUNT1 | GRP | RUNNING_COUNT
-: | --: | ----: | -----: | --: | ------------:
1 | 1 | 0 | 3 | 1 | 3
1 | 2 | 0 | 2 | 1 | 5
1 | 3 | 0 | 6 | 1 | 11
1 | 4 | 1 | 2 | 1 | 13
1 | 5 | 0 | 3 | 0 | 3
1 | 6 | 0 | 5 | 0 | 8
2 | 1 | 0 | 2 | 1 | 2
2 | 2 | 1 | 1 | 1 | 3
2 | 3 | 0 | 3 | 0 | 3

How to check for continuous column count via datatable?

I have a datatable below and I wanted to check the condition if the latest columns have total count of more then 7 then the function will do something but my current solution is only able to count the number of 1 in the datatable but unable to identify the value 1 is consecutive from column 7 to column 14.
-------------------------------------------------------------------
Id | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
-------------------------------------------------------------------
kek | 1 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
Solution
Sub CheckExtraday()
Dim count1 As Integer = 0
Dim sql As String = "Select * from LeaveSystem WHERE EmpID ='" + Session("empID") + "' and Year='" + Session("year") + "' and Month='" + Session("month") + "'"
Dim dt As DataTable = getDTms(sql)
For I As Integer = 0 To dt.Rows.Count - 1
For k As Integer = 2 To dt.Columns.Count - 1
If dt.Rows(I).Item(k).Equals("1") = True Then
count1 = count1 + 1
End If
Next k
Next I
If count1 > 7 Then 'output = 10
'do something
End If
End Sub
Edit :
consecutive count from month 5 column 11 to month 6 column 1-5
----------------------------------------------------------------------------
Id | month | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
----------------------------------------------------------------------------
kek | 5 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 |
kek | 6 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
If I understand you correctly, you seem to be trying to get the number of consecutive cells that have a value of 1. If so, you can simply reset the value of count1 whenever the cell's value is not 1:
If dt.Rows(I).Item(k).ToString() = "1" Then
count1 += 1
Else
count1 = 0
End If
If you want to keep the latest consecutive 1 values even if followed by zeros, you can do something like this:
Dim latestConsecutiveCount As Integer
If dt.Rows(I).Item(k).ToString() = "1" Then
count1 += 1
Else
latestConsecutiveCount = count1
count1 = 0
End If
If latestConsecutiveCount > someValue Then
' Do something
End If

Combining 3 columns with boolean values into one

I've stumbled upon a table with three columns
id | isRed | isBlue | is Green
==============================
1 | 1 | 0 | 0
2 | 1 | 0 | 0
3 | 1 | 0 | 0
4 | 0 | 1 | 0
5 | 0 | 1 | 0
6 | 0 | 1 | 0
7 | 0 | 0 | 1
8 | 0 | 1 | 0
9 | 0 | 0 | 1
10 | 0 | 0 | 0
I want to create query as simple as possible to transform it into something like that:
id | Color
==============================
1 | red
2 | red
3 | red
4 | blue
5 | blue
6 | blue
7 | green
8 | blue
9 | green
10 | 0
The values can't be true in two different columns and I can't alter the database. I need it to append it to quite long query with as little complication as possible. Any ideas?
With a select and case:
select id,
(case when isRed = 1 then 'red'
when isBlue = 1 then 'blue'
when isGreen = 1 then 'green'
else '0'
end) as color
from t;