Select column names based on max value by row - sql

I need select column name based on max value by row. I have snowflake database table:
id cars_cat1 cars_cat2 cars_cat_3
a01 5 2 8
a02 6 1 5
a03 6 5 12
a04 3 9 1
Where is IDs and many categories with counts. I need new column, with category name, where count is max.
Output:
id max_category
a01 cars_cat_3
a02 cars_cat1
a03 cars_cat_3
a04 cars_cat2
I try window functions... without success.

You can use the function GREATEST() in a CASE expression:
SELECT id,
CASE GREATEST(cars_cat1, cars_cat2, cars_cat_3)
WHEN cars_cat1 THEN 'cars_cat1'
WHEN cars_cat2 THEN 'cars_cat2'
WHEN cars_cat3 THEN 'cars_cat3'
END max_category
FROM tablename

Related

Snowflake table replace nulls with multiple values

I have database table at Snowflake, with NULL values.
id
month
a01
5
a02
6
b01
6
b04
NULL
I need transform it as this example:
id
month
a01
5
a02
6
b01
6
b04
7
b04
8
I must replace NULLs with multiple values (with 2 values: 7 and 8 - summer months). So from each NULL row I need to make two rows.
The simplest way to do this would be with two separate statements, one to insert an extra row and one to update the existing NULL value:
INSERT INTO tab (id, month)
SELECT id, 8 as month
FROM tab
WHERE month is NULL;
followed by
UPDATE tab
SET month = 7
WHERE month is NULL;
Result:
id
month
a01
5
a02
6
b01
6
b04
7
b04
8
See this db<>fiddle.

Sql – dividing of two results from select count query

I have a table tbl_casebase :
kd_casebase kd_penyakit kd_gejala
---------------------------------
1 P01 G01
3 P01 G03
4 P02 G03
5 P02 G04
6 P03 G04
7 P03 G05
8 P03 G06
9 P03 G07
10 P04 G07
11 P04 G08
12 P05 G08
13 P05 G09
14 P05 G10
15 P06 G10
16 P06 G11
17 P06 G12
18 P07 G12
19 P07 G13
20 P07 G14
21 P07 G15
22 P08 G15
23 P08 G16
24 P09 G17
25 P09 G18
I execute first select count query :
SELECT
kd_penyakit, COUNT(kd_penyakit) AS count1
FROM
tbl_casebase
WHERE
kd_gejala = 'G01' OR kd_gejala = 'G03'
GROUP BY
kd_penyakit
Then I execute second select count query :
SELECT
kd_penyakit, COUNT(kd_penyakit) AS count2
FROM
tbl_casebase
GROUP BY
kd_penyakit
Now what I want to do is dividing both of the results, so should be like this :
Result #1:
kd_penyakit count1
-------------------
P01 2
P02 1
Result #2:
kd_penyakit count2
-------------------
P01 2
P02 2
P03 4
P04 2
P05 3
P06 3
P07 4
P08 2
P09 2
And the divide process is like this :
2/2=1
1/2=0,5
0/4=0
0/2=0
0/3=0
and others
So how to write the query?
I've seen similar post btw but it does not match what I want.
You can use conditional counting - conditional statement within the count() function. Count function counts any non-null value, so if the criteria are met, a non-null value is returned, otherwise null. This way there is no need for subqueries and joins:
SELECT kd_penyakit, COUNT(case when kd_gejala in ('G01','G03') then 1 else null end)/COUNT(kd_penyakit) AS count1
FROM tbl_casebase
GROUP BY kd_penyakit

SQL - Datediff between rows with Rank Applied

I am trying to work out how to to apply a datediff between rows where a rank is applied to the USER ID;
Example of how the data below;
UserID Order Number ScanDateStart ScanDateEnd Minute Difference Rank | Minute Difference Rank vs Rank+1
User1 10-24 10:20:00 10:40:00 20 1 | 5
User1 10-25 10:45:00 10:50:00 5 2 | 33
User1 10-26 11:12:00 11:45:00 33 3 | NULL
User2 10-10 00:09:00 00:09:20 20 1 | 4
User2 10-11 00:09:24 00:09:25 1 2 | 15
User2 10-12 00:09:40 00:10:12 32 3 | 3
User2 10-13 00:10:15 00:10:35 20 4 | NULL
What i'm looking for is how to code the final column of this table.
The rank is applied to UserID ordered by ScanDateStart.
Basically, i want to know the time between the ScanDateEnd of Rank 1, to ScanDateStart of Rank2, and so on, but for each user.... (calculating time between order processing etc)
Appreciate the help
This can be achieved by performing a LEFT JOIN to the same table on the UserID column and the Rank column, plus 1.
The following (simplified) pseudo-code should illustrate how to achieve this:
SELECT R.UserID,
R.Rank,
R1.Diff
FROM Rank R
LEFT JOIN Rank R1 ON R1.UserID = R.UserID AND R1.Rank = R.Rank + 1
Effectively, you are showing the UserID and Rank from the current row, but the Difference from the row of the same UserID with the Rank + 1.

Access SQL - Select only the last sequence

I have a table with an ID and multiple informative columns. Sometimes however, I can have multiple data for an ID, so I added a column called "Sequence". Here is a shortened example:
ID Sequence Name Tel Date Amount
124 1 Bob 873-4356 2001-02-03 10
124 2 Bob 873-4356 2002-03-12 7
124 3 Bob 873-4351 2006-07-08 24
125 1 John 983-4568 2007-02-01 3
125 2 John 983-4568 2008-02-08 13
126 1 Eric 345-9845 2010-01-01 18
So, I would like to obtain only these lines:
124 3 Bob 873-4351 2006-07-08 24
125 2 John 983-4568 2008-02-08 13
126 1 Eric 345-9845 2010-01-01 18
Anyone could give me a hand on how I could build a SQL query to do this ?
Thanks !
You can calculate the maximum sequence using group by. Then you can use join to get only the maximum in the original data.
Assuming your table is called t:
select t.*
from t join
(select id, MAX(sequence) as maxs
from t
group by id
) tmax
on t.id = tmax.id and
t.sequence = tmax.maxs

How to create an internal numbering of occurrences with SQL

How can I create a new column (inCount) with numbering of occurrences in a specific column?
Here is an example:
id name inCount
1 Orly 1
2 Ernest 1
3 Rachel 1
4 Don 1
5 Don 2
6 Ernest 2
7 Angela 1
8 Ernest 3
9 David 1
10 Rachel 2
11 Sully 1
12 Sully 2
13 Rachel 3
14 David 2
15 David 3
16 Kevin 1
17 Kevin 2
18 Orly 2
19 Angela 2
20 Sully 3
21 Kevin 3
22 Don 3
23 Orly 3
24 Angela 3
Don from id 5 is numbered 2 because Don appears in id 4 too.
Don from id 22 is numbered 3 due to the above preceding occurrences.
I use MS SQL SERVER 2008 R2 Express edition.
Thanks.
You could use partition by, like:
select row_number() over (partition by name order by id) as inCount
, *
from YourTable
order by
id
This should work
SELECT id, Name, ROW_NUMBER() OVER(PARTITION BY Name ORDER BY id)
FROM table
ORDER BY id
EDIT: Added order by clause on the select in order to show results in same order indicated by OP. The ORDER BY in the ROW_NUMBER did not change the outcome, but I changed to id as it will keep the row_number correct for the sample data.