Parent and relevant child as loop maner - plsql

i have data as below
A B
1001 601
1002 1001
1003 1002
1004 1002
1005 1002
I need output as
1001
1002
1003
1001
1002
1004
1001
1002
1005
please help me

Try below code.
WITH sample_data AS(
SELECT '1001' A, '601' B FROM dual UNION ALL
SELECT '1002' A, '1001' B FROM dual UNION ALL
SELECT '1003' A, '1002' B FROM dual UNION ALL
SELECT '1004' A, '1002' B FROM dual UNION ALL
SELECT '1005' A, '1002' B FROM dual
)
SELECT TRIM(COLUMN_VALUE) tree_path
FROM
(
SELECT SUBSTR(SYS_CONNECT_BY_PATH(A, ','),2) tree_path
FROM sample_data
WHERE CONNECT_BY_ISLEAF = 1
start with A = '1001'
CONNECT BY PRIOR A = B
), XMLTABLE(('"' || REPLACE(tree_path, ',', '","') || '"'))

Related

sqlite multiple query conditions

I've searched but can't find the right answer, and I'm going round in circles.
I have
CREATE TABLE History (yr Int, output Int, cat Text);
yr output cat
---------- ---------- ----------
2015 10 a
2016 20 a
2017 30 a
2018 50 a
2019 70 a
2015 100 b
2016 200 b
2017 300 b
2018 500 b
2019 700 b
2015 1000 c
2016 2000 c
2017 3000 c
2018 5000 c
2019 7000 c
2015 10000 d
2016 20000 d
2017 30000 d
2018 50000 d
2019 70000 d
I've created two views
CREATE VIEW Core AS select * from History where cat = "c" or cat = "d";
CREATE VIEW Plus AS select * from History where cat = "a" or cat = "b";
My query is
select distinct yr, sum(output), (select sum(output) from core group by yr) as _core, (select sum(output) from plus group by yr) as _plus from history group by yr;
yr sum(output) _core _plus
---------- ----------- ---------- ----------
2015 11110 11000 110
2016 22220 11000 110
2017 33330 11000 110
2018 55550 11000 110
2019 77770 11000 110
Each of the individual queries works but _core and _plus columns are wrong when it's all put together. How should I approach this please.
You may generate your expected output without a view, using a single query with conditional aggregation:
SELECT
yr,
SUM(output) AS sum_output,
SUM(CASE WHEN cat IN ('c', 'd') THEN output ELSE 0 END) AS _core,
SUM(CASE WHEN cat IN ('a', 'b') THEN output ELSE 0 END) AS _plus
FROM History
GROUP BY
yr;
If you really wanted to make your current approach work, one way would be to just join the two views by year. But that would leave open the possibility that each view might not have every year present.

PLSQL Dynamic Row Count in results

In PL SQL is there a way to produce the Order Count per customer as follows... Thanks for your help.
Cust Order# Order Count
ABC1 011 1
ABC1 052 2
ABC1 199 3
BBA1 150 1
BBA1 158 2
Thanks
Gavin
If I understood you correctly, a little bit of analytics might do the job. Here's an example:
SQL> with test (cust, order#) as
2 (select 'ABC1', '011' from dual union all
3 select 'ABC1', '052' from dual union all
4 select 'ABC1', '199' from dual union all
5 select 'BBA1', '150' from dual union all
6 select 'BBA1', '158' from dual
7 )
8 select cust, order#,
9 row_number() over (partition by cust order by order#) order_count
10 from test;
CUST ORD ORDER_COUNT
---- --- -----------
ABC1 011 1
ABC1 052 2
ABC1 199 3
BBA1 150 1
BBA1 158 2
SQL>
sounds like you want a GROUP BY such as
select cust, SUM(order_count)
from MyTable
group by cust;
which should yield
cust SUM
ABC1 6
BBA1 3

How can we count the PK and repeat this count for the entire list of PK?

How can we count the PK and repeat this count for the entire list of PK?
For example:
Table A (that contains 3000 registers, for example)
ID
0001
0002
0003
0004
0005
...
Using without any filter, we expect:
COUNT(*) | ID
3000 | 0001
3000 | 0002
3000 | 0003
3000 | 0004
3000 | 0005
...
Bt when using filters to restric the results, the COUNT must reflect according the result in screen for example:
select ...
where ID IN (0001,0002,0003,0004,0005)
Then should be:
COUNT(*) | ID
5 | 0001
5 | 0002
5 | 0003
5 | 0004
5 | 0005
This appears to be very simple, but I'm not able to do this.
I've tried to use rownum, count(PK), max(rownum) and haven't success.
Thanks
This?
SQL> select count(*) from emp;
COUNT(*)
----------
12
SQL> select empno, count(*) over (order by null) cnt from emp;
EMPNO CNT
---------- ----------
7369 12
7499 12
7521 12
7566 12
7654 12
7698 12
7782 12
7839 12
7844 12
7900 12
7902 12
7934 12
12 rows selected.
SQL> select empno, count(*) over (order by null) cnt from emp where deptno = 10;
EMPNO CNT
---------- ----------
7782 3
7839 3
7934 3
SQL>

How to extract data from three tables using SQL object relational statement in oracle 11g

I have three tables Branch, Account_table and customer. I am trying to write a SQL statement for:
At each branch find customers who have the highest balance in their savings account. Displaying their names, the balance, the branch ID and the free overdraft limit in their current accounts.
I have created three tables and insert data:
Branch Table
BID BADDRESS.STREET BADDRESS.CITY BADDRESS.P
---------- -------------------- -------------------- ----------
901 Nicholson Street Edinburgh EH11 5AB
906 East End Garden Glasgow G181QP
912 Fredrick Street London LA112AS
918 Zink Terrace Edinburgh EH149UU
Account_table
ACCNUM ACCTYPE BALANCE BID.BID INRATE LIMITOFFREEOD OPENDATE
------- --------------- ---------- ---------- ---------- ------------- --------
1001 current 820.5 901 .005 800 01-MAY-11
1010 saving 2155 906 .02 0 08-MAR-10
1002 current 2600 912 .005 1000 10-APR-13
1011 saving 4140 918 .02 0 24-OCT-13
Customer Table
CUSTID CADDRESS.STREET CADDRESS.CITY CADDRESS.POSTCODE CNAME.FIRSTNAME CNAME.SURNAME
---------- -------------------- ----------- -------------------- --------------- -----------
1002 Adam Street Edinburgh EH112LQ Jack Smith
1003 Adam Street Edinburgh EH112LQ Anna Smith
1004 New Tweed Edinburgh EH1158L Liam Bain
1005 Dundas Street Edinburgh EH119MN Usman Afaque
1006 St Andres Square Edinburgh EH12LNM Claire Mackintosh
Branch(bID, street, city, p_code, bPhone)
Account(accNum, accType, balance, bID, inRate, limitOfFreeOD, openDate)
Customer(custID, street, city, postCode, title, firstName, surName, custHomePhone,custMobile1, custMobile2, niNum)
Bold is primary key Italic is foreign key (In object relational we don't use Join if I am right).
This what I am trying to do but failed
select c.custid,
(select max(balance) from account_table a
where c.CUSTID = a.bid.bid
and a.acctype='saving' )as highest_saving,
c.cname.firstname,c.CNAME.surname
from customer c;
Any help? Thanks.
You are missing custID column in account table. I have added a few more rows of data to create the test case for your requirement.
drop table acct;
drop table branch;
drop table customer;
create table branch(bid number primary key, addr_street varchar2(100), addr_city varchar2(100), addr_p varchar2(20));
insert into branch values(901,'Nicholson Street','Edinburgh','EH11 5AB');
insert into branch values(906,'East End Garden','Glasgow','G181QP');
insert into branch values(912,'Fredrick Street','London','LA112AS');
insert into branch values(918,'Zink Terrace','Edinburgh','EH149UU');
commit;
select * from branch;
Output:
BID ADDR_STREET ADDR_CITY ADDR_P
901 Nicholson Street Edinburgh EH11 5AB
906 East End Garden Glasgow G181QP
912 Fredrick Street London LA112AS
918 Zink Terrace Edinburgh EH149UU
create table customer(custid number primary key, caddr_street varchar2(100), caddr_city varchar2(100),
caddr_p varchar2(10), fname varchar2(100), lname varchar2(100));
insert into customer values(1002,'Adam Street','Edinburgh','EH112LQ','Jack','Smith');
insert into customer values(1003,'Adam Street','Edinburgh','EH112LQ','Anna','Smith');
insert into customer values(1004,'New Tweed','Edinburgh','EH1158L','Liam','Bain');
insert into customer values(1005,'Dundas Street','Edinburgh','EH119MN','Usman','Afaque');
insert into customer values(1006,'St Andres Square','Edinburgh','EH12LNM','Claire','Mackintosh');
commit;
select * from customer;
Output:
CUSTID CADDR_STREET CADDR_CITY CADDR_P FNAME LNAME
1002 Adam Street Edinburgh EH112LQ Jack Smith
1003 Adam Street Edinburgh EH112LQ Anna Smith
1004 New Tweed Edinburgh EH1158L Liam Bain
1005 Dundas Street Edinburgh EH119MN Usman Afaque
1006 St Andres Square Edinburgh EH12LNM Claire Mackintosh
create table acct(accnum number primary key, acctype varchar2(20), balance number, bid number
constraint acct_fk1 references branch(bid),
inrate number, LIMITOFFREEOD number, OPENDATE date, custid number
constraint acct_fk2 references customer(custid));
insert into acct values(1001,'current',820.5,901,0.005,800,to_date('01-MAY-11','dd-mon-yy'),1002);
insert into acct values(1010,'saving',2155,906,0.02,0,to_date('08-MAR-10','dd-mon-yy'),1002);
insert into acct values(1002,'current',2600,912,0.005,1000,to_date('10-APR-13','dd-mon-yy'),1006);
insert into acct values(1011,'saving',4140,918,0.02,0,to_date('24-OCT-13','dd-mon-yy'),1004);
insert into acct values(1012,'saving',4155,906,0.02,0,to_date('08-MAR-10','dd-mon-yy'),1004);
insert into acct values(1013,'current',2600,918,0.005,1000,to_date('10-APR-13','dd-mon-yy'),1004);
commit;
select * from acct;
Output:
ACCNUM ACCTYPE BALANCE BID INRATE LIMITOFFREEOD OPENDATE CUSTID
1001 current 820.5 901 .005 800 01-MAY-11 1002
1010 saving 2155 906 .02 0 08-MAR-10 1002
1002 current 2600 912 .005 1000 10-APR-13 1006
1011 saving 4140 918 .02 0 24-OCT-13 1004
1012 saving 4155 906 .02 0 08-MAR-10 1004
1013 current 2600 918 .005 1000 10-APR-13 1004
select y.fname, y.lname, y.balance, y.bid,ac.accnum,ac.acctype,ac.LIMITOFFREEOD
from (select *
from (select b.bid, c.custid, a.accnum,a.balance,
row_number() over(partition by b.bid order by a.balance desc) rn,
c.fname, c.lname
from acct a
inner join
branch b
on a.bid = b.bid
inner join
customer c
on a.custid = c.custid
where a.acctype = 'saving') x
where x.rn = 1) y
left join
acct ac
on y.custid = ac.custid
and y.bid = ac.bid
and ac.acctype = 'current';
Output:
FNAME LNAME BALANCE BID ACCNUM ACCTYPE LIMITOFFREEOD
Liam Bain 4140 918 1013 current 1000
Liam Bain 4155 906 NULL NULL NULL

PL/SQL, CASE statement or if statement

I am new to PL/SQL
I have a code like this
SELECT f.code,f.date,f.amt, row_number() OVER (PARTITION BY f.code ORDER BY f.date DESC) ranki
FROM advance.alloc f
and shows
CODE DATE AMT ranki
122 12/31/2016 3 1
122 12/31/2015 7 2
122 12/31/2014 3 3
123 6/30/2015 3 1
125 6/30/2015 2 1
125 12/31/2014 8 2
Logic is this
if DATE = 12/__/__ AND ranki = 1 THEN ranki 1, so 122 picks 12/31/2016 3
if DATE = 6/30/__ AND ranki = 1 AND if ranki = 2 exists THEN then pick the second one,so 125 picks 12/31/2014 8
if 6/30__ and ranki is ONLY 1 shows Blank on date LIKE 123
so I would like to show
122 12/31/2016 3
123 __________ 3
125 12/31/2014 8
How can I code like this PL/SQL?
WHEN to_char(af.date,'MM') = 12 AND af.ranki = 1 THEN af.date END
I could code first logic, but I can not figure out how to code the rest of the logic
Thanks
Why in PL/SQL? Or do you mean "in Oracle SQL"? (The solution below uses standard analytic functions, so it is not specific to Oracle.)
Add more information through analytic functions, in addition to ranki. Extract the month from the row with ranki = 1, and also the total count for each code. Then the WHERE clause can follow your logic step by step.
with
f ( code, dt, amount ) as (
select 122, to_date('12/31/2016', 'mm/dd/yyyy'), 3 from dual union all
select 122, to_date('12/31/2015', 'mm/dd/yyyy'), 7 from dual union all
select 122, to_date('12/31/2014', 'mm/dd/yyyy'), 3 from dual union all
select 123, to_date( '6/30/2015', 'mm/dd/yyyy'), 3 from dual union all
select 125, to_date( '6/30/2015', 'mm/dd/yyyy'), 2 from dual union all
select 125, to_date('12/31/2014', 'mm/dd/yyyy'), 8 from dual
)
-- End of simulated data (for testing purposes only, not part of the solution).
-- SQL query begins BELOW THIS LINE.
select code, case when mth = 12 or ranki = 2 then dt end as dt, amount
from ( select code, dt, amount,
first_value(extract (month from dt))
over (partition by code order by dt desc) as mth,
row_number() over (partition by code order by dt desc) as ranki,
count(*) over (partition by code) as cnt
from f
)
where mth = 12 and ranki = 1
or cnt = 1
or mth = 6 and ranki = 2
;
CODE DT AMOUNT
---- ---------- ------
122 12/31/2016 3
123 3
125 12/31/2014 8

Resources