Assume that there is a column which has 2 attribute a and b. I only want it to consider only a to the overall case condition. How do I apply that in case statement?
Something like:
Case when student> 100 then 'big class'
else ''
End [big class ]
*exclude class 10th.*
I don't get your question, If you want to get the "big class" of Divison A ,It is not necessary for using case. or you have additional requirement.
;WITH SampleTable(GroupNo,NoOfStudent,Division)AS(
SELECT 'grp 1',105,'a' UNION ALL
SELECT 'grp 2',107,'a' UNION ALL
SELECT 'grp 3',108,'b' UNION ALL
SELECT 'grp 4',110,'b' UNION ALL
SELECT 'grp 5',85,'b' UNION ALL
SELECT 'grp 6',84,'a' UNION ALL
SELECT 'grp 7',83,'a' UNION ALL
SELECT 'grp 8',110,'b' UNION ALL
SELECT 'grp 9',105,'a' UNION ALL
SELECT 'grp 10',140,'b'
)
--1
SELECT * FROM SampleTable WHERE Division='A' AND NoOfStudent>100
GroupNo NoOfStudent Division
------- ----------- --------
grp 1 105 a
grp 2 107 a
grp 9 105 a
--2
SELECT * ,CASE WHEN Division='A' AND NoOfStudent>100 THEN 'big class' ELSE '' END AS [BigClass]
FROM SampleTable
GroupNo NoOfStudent Division BigClass
------- ----------- -------- ---------
grp 1 105 a big class
grp 2 107 a big class
grp 3 108 b
grp 4 110 b
grp 5 85 b
grp 6 84 a
grp 7 83 a
grp 8 110 b
grp 9 105 a big class
grp 10 140 b
Related
I have a table where I have to pick one of two if it is present. For example if a ID has ACCEPTED and SETTLED , I have to only pick SETTLED else the remaining. Only ACCEPTED/SETTLED always comes as duplicates
Input:
Output:
Query Tried:
SELECT * FROM TABLE
WHERE CASE WHEN "Status" IN ('ACCEPTED','SETTLED') THEN 'SETTLED'
WHEN "Status" IN ('ACCEPTED') THEN 'ACCEPTED'
ELSE "Status" END In ('SETTLED','ACCEPTED')
If your groups are defined by ID and Amount, you could do something like:
SELECT
t.ID,
MAX(t.Status),
t.Amount
FROM t
GROUP BY t.ID, t.Amount
ORDER BY t.ID
db<>fiddle
This is one option (sample data in lines #1 - 7; query begins at line #8). It ranks statuses so that SETTLED comes first, and then the rest of them.
SQL> with test (id, status, amount) as
2 (select 1, 'ACCEPTED', 13 from dual union all
3 select 1, 'SETTLED' , 13 from dual union all
4 select 2, 'SETTLED' , 155 from dual union all
5 select 3, 'ACCEPTED', 123 from dual union all
6 select 4, 'REJECTED', 140 from dual
7 )
8 select id, status, amount
9 from (select id, status, amount,
10 row_number() over (partition by id
11 order by case when status = 'SETTLED' then 1 else 2 end) rn
12 from test
13 )
14 where rn = 1;
ID STATUS AMOUNT
---------- -------- ----------
1 SETTLED 13
2 SETTLED 155
3 ACCEPTED 123
4 REJECTED 140
SQL>
I have the columns like this, all columns coming from three different tables.
GROUPID COMPANYID CUSTID DEAL
121 A 1 DEAL1
121 A 1 DEAL2
121 A 1 DEAL3
121 B 2 DEAL1
121 B 2 DEAL2
121 B 2 DEAL3
i want the columns like
GROUPID COMPANYID CUSTID DEAL
121 A 1 DEAL1
DEAL2
DEAL3
B 2 DEAL1
DEAL2
DEAL3
Can you help me with this?
Thanks
Well, from my point of view, this is the client problem, not necessarily SQL one. Any decent reporting tool (such as Oracle Reports Builder, Oracle Apex Classic report, ...) is capable of breaking data on columns you choose.
Even the good, old SQL*Plus knows how to do that.
This is your current result:
SQL> select * from three_tables order by groupid, companyid, custid, deal;
GROUPID COMPANYID CUSTID DEAL
---------- ---------- ---------- -----
121 A 1 DEAL1
121 A 1 DEAL2
121 A 1 DEAL3
121 B 2 DEAL1
121 B 2 DEAL2
121 B 2 DEAL3
6 rows selected.
Break (as I said):
SQL> break on groupid on companyid on custid
SQL>
SQL> select * from three_tables order by groupid, companyid, custid, deal;
GROUPID COMPANYID CUSTID DEAL
---------- ---------- ---------- -----
121 A 1 DEAL1
DEAL2
DEAL3
B 2 DEAL1
DEAL2
DEAL3
6 rows selected.
SQL>
I suggest you do the same - set the breaking option in a tool you use.
i am just enhancing Tim answer by adding lag() window function
WITH yourTable AS (
SELECT 121 AS GROUPID, 'A' AS COMPANYID, 1 AS CUSTID, 'DEAL1' AS DEAL FROM dual UNION ALL
SELECT 121, 'A', 1, 'DEAL2' FROM dual UNION ALL
SELECT 121, 'A', 1, 'DEAL3' FROM dual UNION ALL
SELECT 121, 'B', 2, 'DEAL1' FROM dual UNION ALL
SELECT 121, 'B', 2, 'DEAL2' FROM dual UNION ALL
SELECT 121, 'B', 2, 'DEAL3' FROM dual UNION ALL
SELECT 123, 'c', 2, 'DEAL1' FROM dual UNION ALL
SELECT 123, 'c', 2, 'DEAL2' FROM dual
),
cte AS (
SELECT t.*, ROW_NUMBER() OVER (PARTITION BY GROUPID, COMPANYID, CUSTID ORDER BY DEAL) rn
FROM yourTable t
)
,cte1 as(
SELECT
GROUPID,
CASE WHEN rn = 1 THEN COMPANYID END AS COMPANYID,
CASE WHEN rn = 1 THEN CUSTID END AS CUSTID,
DEAL
FROM cte t
ORDER BY
GROUPID,
t.COMPANYID,
CUSTID,
DEAL) select case when lag(GROUPID)over(order by GROUPID)=GROUPID
then null else GROUPID end Gid,COMPANYID,CUSTID,DEAL from cte1
DEMO
This should not be done in SQL. You should be doing this in the reporting tool that you use. GroupID, CompanyID and CustID can be the dimensions and Deal can be the measure.
If you want to do that in SQL, then you probably need to use as many analytic functions as you have columns to outpout
select
case when GROUPID != lag(GROUPID, 1, 999999999)over(partition by GROUPID order by GROUPID) then GROUPID else null end GROUPID
, case when COMPANYID != lag(COMPANYID, 1, 'ZZZZZZZZZ')over(partition by GROUPID, COMPANYID order by COMPANYID) then COMPANYID else null end COMPANYID
, case when CUSTID != lag(CUSTID, 1, 999999999)over(partition by GROUPID, COMPANYID, CUSTID order by CUSTID) then CUSTID else null end CUSTID
, case when DEAL != lag(DEAL, 1, 'ZZZZZZZZZ')over(partition by GROUPID, COMPANYID, CUSTID, DEAL order by DEAL) then DEAL else null end DEAL
from your_table
;
I have a table in which I have multiple IDs which can have a value or 0. The IDs come from different sources so I would like to know what is the percentage of IDs with the value 0 as a percentage of total IDs, for each source file.
Sample Data:
ID Source
1 aaa
0 aaa
2 bbb
0 ccc
3 ccc
0 ccc
5 aaa
0 bbb
6 bbb
7 bbb
I need to display Output like:
CountOfIDs0 TotalIDs Source PercentageIDs0
2 3 ccc 66.6%%
1 3 aaa 33.3%%
1 4 bbb 25%
Thanks!
If you want a result like 66.6% rather than 66.7%, you would use trunc() rather than round() (although the latter is probably better). And you need to round a/b to three decimal places, so there is one left after you multiply by 100.
Then, you can have both counts in one query, and you can add the percentage calculation also in the same query.
select count(case when propkey = 0 then 1 end) countid0,
count(propkey) totalidcount,
source,
to_char(round(count(case when properkey = 0 then 1 end)/count(properkey), 3)*100)
|| '%' percentageids0
from......
Apply round function.
select count(id) as TotalIDs ,Source, sum(case when id=0 then 1 end) countid0,
to_char((sum(case when id=0 then 1 end)/count(id))*100)||'%' as PercentageIDs0
from Table1 group by Source
For Unique record you have to use DISTINCT Query
I would do it that way:
With MyRows AS (
SELECT 1 ID, 'aaa' SOURCE FROM DUAL UNION ALL
SELECT 0, 'aaa' FROM DUAL UNION ALL
SELECT 2, 'bbb' FROM DUAL UNION ALL
SELECT 0, 'ccc' FROM DUAL UNION ALL
SELECT 3, 'ccc' FROM DUAL UNION ALL
SELECT 0, 'ccc' FROM DUAL UNION ALL
SELECT 5, 'aaa' FROM DUAL UNION ALL
SELECT 0, 'bbb' FROM DUAL UNION ALL
SELECT 6, 'bbb' FROM DUAL UNION ALL
SELECT 7, 'bbb' FROM DUAL
)
SELECT
DISTINCT SOURCE,
SUM(CASE WHEN ID = 0 THEN 1 ELSE 0 END) OVER (PARTITION BY SOURCE) ZERO_IDS,
COUNT(ID) OVER (PARTITION BY SOURCE) TOTAL_IDS,
(100 * SUM(CASE WHEN ID = 0 THEN 1 ELSE 0 END) OVER (PARTITION BY SOURCE))/(COUNT(ID) OVER (PARTITION BY SOURCE)) PERCENTAGE
FROM MyRows
;
I calculated percentage of values in a column by using below query
Select A.,B., to_char((A.count_service/B.count_total)*100)||'%' from
(Select type_cd, count(type_cd) as count_type
from table1
group by type_cd) A
cross join
(Select count(type_cd) as count_total
from table1) B ;
select Source,
ROUND(100*number/sum(number) OVER (PARTITION BY p),2) as percentage,
sum(number) OVER (PARTITION BY p) as total
from(
select 1 p,
Source ,
count(Source) number
from declaration_assessment_result
GROUP by Source
)x
My table seems like this;
A B
1 100
1 102
1 105
2 100
2 105
3 100
3 102
I want output like this:
A Count(B)
1 3
1,2 2
1,2,3 3
2 2
3 2
2,3 2
How can i do this?
I try to use listagg but it didn't work.
I suspect that you want to count the number of sets of A that are in the data -- and that your sample results are messed up.
If so:
select grp, count(*)
from (select listagg(a, ',') within group (order by a) as grp
from t
group by b
) b;
This gives you the counts for the full combinations present in the data. The results would be:
1,2,3 1
1,3 1
1,2 1
You can get the original number of rows by doing:
select grp, sum(cnt)
from (select listagg(a, ',') within group (order by a) as grp, count(*) as cnt
from t
group by b
) b;
Oracle Setup:
CREATE TABLE table_name ( A, B ) AS
SELECT 1, 100 FROM DUAL UNION ALL
SELECT 1, 102 FROM DUAL UNION ALL
SELECT 1, 105 FROM DUAL UNION ALL
SELECT 2, 100 FROM DUAL UNION ALL
SELECT 2, 105 FROM DUAL UNION ALL
SELECT 3, 100 FROM DUAL UNION ALL
SELECT 3, 102 FROM DUAL;
Query:
SELECT A,
COUNT(B)
FROM (
SELECT SUBSTR( SYS_CONNECT_BY_PATH( A, ',' ), 2 ) AS A,
B
FROM table_name
CONNECT BY PRIOR B = B
AND PRIOR A + 1 = A
)
GROUP BY A
ORDER BY A;
Output:
A COUNT(B)
----- ----------
1 3
1,2 2
1,2,3 1
2 2
2,3 1
3 2
I have a table as below.i am using oracle 10g.
TableA
------
id status
---------------
1 R
1 S
1 W
2 R
i need to get distinct ids along with their status. if i query for distinct ids and their status i get all 4 rows.
but i should get only 2. one per id.
here id 1 has 3 distinct statuses. here i should get only one row based on priority.
first priority is to 'S' , second priority to 'W' and third priority to 'R'.
in my case i should get two records as below.
id status
--------------
1 S
2 R
How can i do that? Please help me.
Thanks!
select
id,
max(status) keep (dense_rank first order by instr('SWR', status)) as status
from TableA
group by id
order by 1
fiddle
select id , status from (
select TableA.*, ROW_NUMBER()
OVER (PARTITION BY TableA.id ORDER BY DECODE(
TableA.status,
'S',1,
'W',2,
'R',3,
4)) AS row_no
FROM TableA)
where row_no = 1
This is first thing i would do, but there may be a better way.
Select id, case when status=1 then 'S'
when status=2 then 'W'
when status=3 then 'R' end as status
from(
select id, max(case when status='S' then 3
when status='W' then 2
when status='R' then 1
end) status
from tableA
group by id
);
To get it done you can write a similar query:
-- sample of data from your question
SQL> with t1(id , status) as (
2 select 1, 'R' from dual union all
3 select 1, 'S' from dual union all
4 select 1, 'W' from dual union all
5 select 2, 'R' from dual
6 )
7 select id -- actual query
8 , status
9 from ( select id
10 , status
11 , row_number() over(partition by id
12 order by case
13 when upper(status) = 'S'
14 then 1
15 when upper(status) = 'W'
16 then 2
17 when upper(status) = 'R'
18 then 3
19 end
20 ) as rn
21 from t1
22 ) q
23 where q.rn = 1
24 ;
ID STATUS
---------- ------
1 S
2 R
select id,status from
(select id,status,decode(status,'S',1,'W',2,'R',3) st from table) where (id,st) in
(select id,min(st) from (select id,status,decode(status,'S',1,'W',2,'R',3) st from table))
Something like this???
SQL> with xx as(
2 select 1 id, 'R' status from dual UNION ALL
3 select 1, 'S' from dual UNION ALL
4 select 1, 'W' from dual UNION ALL
5 select 2, 'R' from dual
6 )
7 select
8 id,
9 DECODE(
10 MIN(
11 DECODE(status,'S',1,'W',2,'R',3)
12 ),
13 1,'S',2,'W',3,'R') "status"
14 from xx
15 group by id;
ID s
---------- -
1 S
2 R
Here, logic is quite simple.
Do a DECODE for setting the 'Priority', then find the MIN (i.e. one with Higher Priority) value and again DECODE it back to get its 'Status'
Using MOD() example with added values:
SELECT id, val, distinct_val
FROM
(
SELECT id, val
, ROW_NUMBER() OVER (ORDER BY id) row_seq
, MOD(ROW_NUMBER() OVER (ORDER BY id), 2) even_row
, (CASE WHEN id = MOD(ROW_NUMBER() OVER (ORDER BY id), 2) THEN NULL ELSE val END) distinct_val
FROM
(
SELECT 1 id, 'R' val FROM dual
UNION
SELECT 1 id, 'S' val FROM dual
UNION
SELECT 1 id, 'W' val FROM dual
UNION
SELECT 2 id, 'R' val FROM dual
UNION -- comment below for orig data
SELECT 3 id, 'K' val FROM dual
UNION
SELECT 4 id, 'G' val FROM dual
UNION
SELECT 1 id, 'W' val FROM dual
))
WHERE distinct_val IS NOT NULL
/
ID VAL DISTINCT_VAL
--------------------------
1 S S
2 R R
3 K K
4 G G