Sql – dividing of two results from select count query - sql

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

Related

How to get top values when there is a tie

I am having difficulty figuring out this dang problem. From the data and queries I have given below I am trying to see the email address that has rented the most movies during the month of September.
There are only 4 relevant tables in my database and they have been anonymized and shortened:
Table "cust":
cust_id
f_name
l_name
email
1
Jack
Daniels
jack.daniels#google.com
2
Jose
Quervo
jose.quervo#yahoo.com
5
Jim
Beam
jim.beam#protonmail.com
Table "rent"
inv_id
cust_id
rent_date
10
1
9/1/2022 10:29
11
1
9/2/2022 18:16
12
1
9/2/2022 18:17
13
1
9/17/2022 17:34
14
1
9/19/2022 6:32
15
1
9/19/2022 6:33
16
3
9/1/2022 18:45
17
3
9/1/2022 18:46
18
3
9/2/2022 18:45
19
3
9/2/2022 18:46
20
3
9/17/2022 18:32
21
3
9/19/2022 22:12
10
2
9/19/2022 11:43
11
2
9/19/2022 11:42
Table "inv"
mov_id
inv_id
22
10
23
11
24
12
25
13
26
14
27
15
28
16
29
17
30
18
31
19
31
20
32
21
Table "mov":
mov_id
titl
rate
22
Anaconda
3.99
23
Exorcist
1.99
24
Philadelphia
3.99
25
Quest
1.99
26
Sweden
1.99
27
Speed
1.99
28
Nemo
1.99
29
Zoolander
5.99
30
Truman
5.99
31
Patient
1.99
32
Racer
3.99
and here is my current query progress:
SELECT cust.email,
COUNT(DISTINCT inv.mov_id) AS "Rented_Count"
FROM cust
JOIN rent ON rent.cust_id = cust.cust_id
JOIN inv ON inv.inv_id = rent.inv_id
JOIN mov ON mov.mov_id = inv.mov_id
WHERE rent.rent_date BETWEEN '2022-09-01' AND '2022-09-31'
GROUP BY cust.email
ORDER BY "Rented_Count" DESC;
and here is what it outputs:
email
Rented_Count
jack.daniels#google.com
6
jim.beam#protonmail.com
6
jose.quervo#yahoo.com
2
and what I want it to be outputting:
email
jack.daniels#google.com
jim.beam#protonmail.com
From the results I am actually getting I have a tie for first place (Jim and Jack) and that is fine but I would like it to list both tieing email addresses not just Jack's so you cant do anything with rows or max I don't think.
I think it must have something to do with dense_rank but I don't know how to use that specifically in this scenario with the count and Group By?
Your creativity and help would be appreciated.
You're missing the FETCH FIRST ROWS WITH TIES clause. It will work together with the ORDER BY clause to get you the highest values (FIRST ROWS), including ties (WITH TIES).
SELECT cust.email
FROM cust
INNER JOIN rent
ON rent.cust_id = cust.cust_id
INNER JOIN inv
ON inv.inv_id = rent.inv_id
INNER JOIN mov
ON mov.mov_id = inv.mov_id
WHERE rent.rent_date BETWEEN '2022-09-01' AND '2022-09-31'
GROUP BY cust.email
ORDER BY COUNT(DISTINCT inv.mov_id) DESC
FETCH FIRST 1 ROWS WITH TIES

SQL Query to keep a running lowest value

I have a table with 2 fields:
Period Time
1 4562
2 4555
3 4570
4 4558
5 4550
6 4570
7 4565
8 4545
9 4550
10 4560
For each period I would like to keep the lowest time in another field so the table would look like this:
Period Time Lowest
1 4562 4562
2 4555 4555
3 4570 4555
4 4558 4555
5 4550 4550
6 4570 4550
7 4565 4550
8 4545 4545
9 4550 4545
10 4560 4545
Thanks
You want a cumulative minimum. You can use ISO/ANSI standard window functions:
select t.*,
min(time) over (order by id) as lowest
from t;
Try the following query
select *,min(time) over (order by period) from YOURTABLENAME
SQL Server 2014

Update Table A from loop data on table B

I want to update table qcard with data every record from q_id table
q_id table field and have 5 record
---------------
q_id groupcode
---- ---------
1 A01
2 A02
3 A03
4 A05
5 A06
qcard table now have data in field qcard 10001-2000
field loop q_id groupcode not data
qcard loop q_id groupcode
----- ---- ---- ---------
10001
10002
10003
10004
10005
10006
10007
10008
10009
10010
I need to update qcard table with all record from q_id table for each loop (loop I set from 01,02,03,....to 99) if finish each loop have all record from q_id table
if works qcard table this data
-------------------------------
qcard loop q_id groupcode
----- ---- ---- ---------
10001 01 1 A01
10002 01 2 A02
10003 01 3 A03
10004 01 4 A04
10005 01 5 A05
10006 02 1 A01
10007 02 2 A02
10008 02 3 A03
10009 02 4 A04
10010 02 5 A05
...... untill
1xxxx 99 1 A01
1xxxx 99 2 A02
1xxxx 99 3 A03
1xxxx 99 4 A04
1xxxx 99 5 A05
Try this Answer,
CREATE TABLE #Numbers(N INT)
INSERT INTO #NUMBERS(N)
SELECT TOP 495 ROW_NUMBER() OVER(ORDER BY T1.NUMBER) AS N
FROM MASTER..spt_values T1
CROSS JOIN MASTER..spt_values t2
SELECT N,CASE WHEN LEN(CAST((N+4)/5 as VARCHAR))<2 THEN '0'+CAST((N+4)/5 as VARCHAR) ELSE CAST((N+4)/5 as VARCHAR) END[Loop]
,CASE WHEN N%10 in(1,6) THEN 1 WHEN N%10 in(2,7) THEN 2 WHEN N%10 in(3,8) THEN 3 WHEN N%10 in(4,9) THEN 4 WHEN N%10 in(5,0) THEN 5 END q_id
from #Numbers
UPDATE A SET A.Loop=B.Loop, AND A.q_id=B.q_id
FROM qcard A,#Numbers B
WHERE (A.qcard%10000)=B.N
UPDATE B
SET B.groupcode=A.groupcode
FROM q_id A,qcard B
WHERE A.q_id=B.q_id
DROP TABLE #Numbers

return the count of row even if null sql server

I trying to do a sql query to get the count for shift for each user
I used this query :
SELECT
COUNT(s.id) AS count, s.user_id
FROM
sarcuser AS u
INNER JOIN
sarcshiftpointuser AS s ON s.user_id = u.id
INNER JOIN
sarcalllevel AS l ON l.id = u.levelid
INNER JOIN
sarcshiftpointtable AS t ON t.shift_id = s.shift_id AND s.table_id = t.table_id
WHERE
(s.shift_id + '' LIKE '2')
AND (CAST(s.xdate AS DATE) BETWEEN CAST(N'2014-01-01' AS DATE) AND CAST(N'2015-01-01' AS DATE))
AND (u.gender + '' LIKE N'%')
AND (u.levelid + '' LIKE N'%')
AND (s.point_id + '' LIKE '2')
GROUP BY
s.user_id
ORDER BY
count
It works very well ... but there is a logic problem :
when the user didn't appear in the shift didn't return the count and I need it to return 0
For example :
user1 user2
shift1 2 2
shift2 5 0
shift3 6 10
but actually the code returns :
user1 user2
shift1 2 2
shift2 5 10
shift3 6
and that's wrong ... how to return the count even if it zero with this condition and this inner join ?
Sample for data in table :
sarcuser :
id firstname lastname gender levelid
52 samy sammour male 1
62 ibrahim jackob male 1
71 rebeca janson female 3
sarcalllevel :
id name
1 field leader
2 leader
3 paramdic
sarcshiftpointtable :
id shift_id table_id name_of_shift point_id
1 1 1 shift1 2
2 2 1 shift2 2
3 3 1 shift3 2
4 1 2 shift1 7
5 2 2 shift2 7
6 3 2 shift3 7
sarcshiftpointuser :
id point_id shift_id table_id user_id xdate
1 2 1 1 62 2014-01-05
2 2 1 1 0 2014-01-05
3 2 1 1 71 2014-01-05
4 2 2 1 0 2014-01-05
5 2 2 1 0 2014-01-05
6 2 2 1 52 2014-01-05
7 2 3 1 52 2014-01-05
8 2 3 1 62 2014-01-05
9 2 3 1 71 2014-01-05
10 2 1 1 71 2014-01-06
11 2 1 1 52 2014-01-06
12 2 1 1 0 2014-01-06
13 2 2 1 62 2014-01-06
14 2 2 1 0 2014-01-06
15 2 2 1 52 2014-01-06
16 2 3 1 62 2014-01-06
17 2 3 1 52 2014-01-06
18 2 3 1 71 2014-01-06
if i apply this query 3 times by changing the shift should return :
52 62 71
shift1 1 2 2
shift2 2 1 0
shift3 2 2 2
in shift2 in sarcshiftpointuser the user 71 is not appear
so when I do the code it will return just to field not three ? the count 0 is not returned
52 62 71
shift2 2 1
to be more specific :
I need to export this table into excel so when the 0 is not return it give me a wrong order and wrong value (logically )
You will need to use a nested query using IFNULL
Take a look to this
http://www.w3schools.com/sql/sql_isnull.asp
Something like,
IFNULL(user,0)
I think you are referring a crosstab query. you can use PIVOT to return your result set. Please refer below link.
Sql Server 2008 Cross Tab Query.
If you give few sample data for sarcuser , sarcshiftpointuser, sarcalllevel & sarcshiftpointtable tables, then we can give you a better answer.

Select an interval of values that is equal or greater than the previous value

My problem is that I don't get the first value in the interval.
The values in the increasing interval in table 1 is Id1-Id3, Id4-Id5, Id9-Id13 and Id14-Id15, but
the result i Table 2 is Id2-Id3, Id5,Id10-Id13 and Id 15 missing Id1, Id4, Id9 and Id14.
I just can't figure out how to get the first value included in the query.
PSS Table containing the datasource:
ID Date Value
1 2012-04-20 0,166666666666667
2 2012-04-25 0,2
3 2012-04-28 0,235294117647059
4 2012-05-05 0,111111111111111
5 2012-05-07 0,416666666666667
6 2012-05-08 0,25
7 2012-05-09 0,166666666666667
8 2012-05-10 0,142857142857143
9 2012-05-11 0,125
10 2012-05-12 0,375
11 2012-05-13 0,5
12 2012-05-14 0,625
13 2012-05-15 0,75
14 2012-05-16 0,625
15 2012-05-17 0,75
And this query:
SELECT Id, Date, Value
FROM PSS p
WHERE p.Value >=
(SELECT Value
FROM PSS
WHERE Id = p.Id-1)
Resulting in tabel 2:
Id Date Value
2 2012-04-25 0,2
3 2012-04-28 0,235294117647059
5 2012-05-07 0,416666666666667
10 2012-05-12 0,375
11 2012-05-13 0,5
12 2012-05-14 0,625
13 2012-05-15 0,75
15 2012-05-17 0,75
Try this
select id, date, value
from PSS p1
where value >= (select p2.amount from PSS p2 where p2.id=p1.id - 1)
or value <= (select p3.amount from PSS p3 where P3.id=p1.id + 1)