i want Oracle Query for Formatted Output - oracle

Following is my table deign
Ecode Degree YOQ
7654321 SSC 2000
7654321 HSC 2002
7654321 Bcom 2006
7654321 MCA 2010
7654322 SSC 2002
7654322 HSC 2004
7654322 Bcom 2007
7654323 SSC 2002
7654323 HSC 2004
7654323 BE 2008
i want following formatted output using oracle query
Ecode Degree year
7654321 SSC,HSC,Bcom,MCA 2000,2002,2006,2010
7654322 SSC,HSC,Bcom 2002,2004,2007
7654323 SSC,HSC,BE 2002,2004,2008
Thanks in Advance
Vivek shah

SELECT ecode,wm_concat(DEGREE),wm_concat(yoQ) FROM TABLE_NAME GROUP BY ecode

Related

Using a 0 rather than skipping the group entirely if nothing is found

How can I use a 0 as a "placeholder" here?
=QUERY(Data!A1:G578, "select G, sum(C) where D='Income' group by G label sum(C) 'Total Income'")
So that
Month
Total Income
August 2021
$784.59
October 2021
$200.00
November 2021
$312.74
becomes
Month
Total Income
August 2021
$784.59
September 2021
$0.00
October 2021
$200.00
November 2021
$312.74
The quickest hacky fix would be just to have an entry of 0$ for September in the data somewhere, but I am wondering if there is a more ""professional"" way to do it

Extracting words from a sentence in oracle

I have table and the table 'test' and it has column filename whilch contains differnt format of sentences.
filename
LA West Employer us Rort October 2015.txt201510
LA loyer sus Rrt April 2017
LA oyer sus Rept April 2018.txt201712
LA oyer sus Ret April 2019.txt201712
LA Eoyer sus Ret Aug 2019.txt201712
LA oyer sus Rort August 2017(2).txt201708
LA Eyer sus Rort August 2018 (1).txt201712
LA Eyer sus Reort Dec 2017.txt201711
LA Emyer sus Report Dec 2018 (1).txt201712
LA Emyer sus Report October- 2018 (1).txt201712
My expected output is:
October 2015
April 2017
Aug 2019
Dec 2017
Each row is containing Month year, I want to extract that part from it.
I tried as below:
SELECT
SubStr(filename,INSTR(filename,'Report')+7,(INSTR(filename,'(')-1)-(INSTR(filename,'Report')+7))res
FROM test ;
select regexp_substr(filename, '[^[:space:]]+[[:space:]][^[:space:]]+$') from table;
It didnot worked.How I can achieve this result?
A possible solution is:
select replace(regexp_substr('LLC Emyer sus Report October- 2018 (1).txt201712', '[[:alpha:]-]+[[:space:]][[:digit:]]{4}'), '-', '')
from dual;
This pattern also works fine
select FILENAME, regexp_substr(FILENAME, '([[:alpha:]]+\s+[[:digit:]]+)\s*(\([[:digit:]]+\))?\.txt.+?$', 1, 1, 'i', 1) expected_output
from your_table

How to create a before or after Trigger that can catch DUP_VAL_ON_INDEX on Oracle PL/SQL

I have a table like this
KD_C KD_PLA KD_T GABUNG BERAKHIR GAJI_PL BUYOUT
---- ------ ---- ---------- ---------- ---------- ----------
C001 MA001 T006 2003 2014 50000 5200000
C002 SC001 T006 2012 2016 65000 20280000
C003 TW001 T006 2005 2018 90000 46800000
C004 TV001 T006 2008 2017 60000 24960000
C005 PC001 T001 2003 2016 80000 24960000
C006 AC001 T001 1996 2014 90000 9360000
C007 DB001 T001 2010 2016 65000 20280000
C008 EH001 T001 2011 2018 85000 44200000
C009 JC001 T002 1996 2014 60000 6240000
C010 SG001 T002 1998 2016 87000 27144000
C011 LS001 T002 2010 2018 81000 42120000
C012 PR001 T002 2004 2016 60000 18720000
C013 JH001 T003 2005 2018 72000 37440000
C014 GC001 T003 2003 2015 65000 13520000
C015 ED001 T003 2010 2018 100000 52000000
C016 GB001 T003 2010 2016 80000 24960000
C017 DG001 T004 2011 2018 73000 37960000
C018 RG001 T004 1992 2014 90000 9360000
C019 PJ001 T004 2011 2018 80000 41600000
C020 RP001 T004 2012 2017 92000 38272000
C021 GB002 T005 2006 2018 102000 53040000
C022 EA001 T005 2011 2015 70000 14560000
C023 HL001 T005 2012 2018 65000 33800000
C024 KW001 T005 2009 2017 67000 27872000
C025 MA001 T005 2017 2022 50000 26000000
C028 MA001 T001 2016 2018 15000 3120000
C029 MA001 T001 2016 2018 15000 3120000
C030 MA001 T001 2016 2018 15000 3120000
And then I tried to make a Trigger for updating instead of insert to the table when duplicate a primary key. The primary key is the first coloumn 'KD_CONTRACT'.
CREATE OR REPLACE TRIGGER INSERT_TABEL_CONTRACT
BEFORE INSERT ON CONTRACT
FOR EACH ROW
DECLARE
KODE VARCHAR2(20);
TEMPCARIKODE NUMBER;
BEGIN
SELECT LPAD(TO_NUMBER(NVL(SUBSTR(MAX(KD_CONTRACT),2),0))+1,3,'0') INTO KODE
FROM CONTRACT;
SELECT COUNT(KD_CONTRACT) INTO TEMPCARIKODE
FROM CONTRACT
WHERE KD_CONTRACT = :NEW.KD_CONTRACT;
IF(TEMPCARIKODE = 0) THEN
:NEW.KD_CONTRACT := 'C'||KODE;
:NEW.GABUNG := TO_NUMBER(TO_CHAR(SYSDATE,'YYYY'));
:NEW.BERAKHIR := :NEW.GABUNG + :NEW.BERAKHIR;
:NEW.BUYOUT := (:NEW.GAJI_PL * 52) * (:NEW.Berakhir-:NEW.Gabung) * 2;
END IF;
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
DBMS_OUTPUT.PUT_LINE('');
DBMS_OUTPUT.PUT_LINE('');
DBMS_OUTPUT.PUT_LINE('ERROR at Line 1:');
DBMS_OUTPUT.PUT_LINE('ORA-20003: Data sudah ada, data akan diupdate!');
END;
/
show err;
anyway maybe the code show that I tried not to update when the primary key is duplicated. But please the until end first.
it show no error... So the trigger successfully created.
then I tried to insert a duplicated primary key.
INSERT INTO CONTRACT VALUES('C001','MA001','T001',2013,2,15000,2500000);
the result
INSERT INTO CONTRACT VALUES('C001','MA001','T001',2013,2,15000,2500000)
*
ERROR at line 1:
ORA-00001: unique constraint (TUGAS.PK_CONTRACT) violated
It did raise ORA-00001 but it never touched the DUP_VAL_ON_INDEX and showed nothing or the custom message.
Anyone have Idea? When it never even touch DUP_VAL_ON_INDEX then how could I event paste an update query at the when case...
Thanks...
* anyway my oracle is XE or express edition.
The EXCEPTION block from your trigger will never be executed since your trigger doesn't contain any INSERT or UPDATE statements.
You have to consider INSTEAD OF Trigger instead.

Database query to select the maximum row with user_id

i need to select the maximum database entry row from the table with the user_id
table name: cd_production
code_cd etaireia etos
______________________
400400 ODEON 1987
400401 ODEON 1986
400412 COLUMBIA 1990
400420 COLUMBIA 1990
400657 LYRA 1965
410000 COLUMBIA 1962
410001 COLUMBIA 1964
410003 PHILIPS 1979
410005 PHILIPS 1971
420430 ODEON 2002
420440 LYRA 2005
420450 COLUMBIA 2009
420460 ODEON 2007
420470 PHILIPS 2008
420480 ODEON 2002
420490 COLUMBIA 2010
500500 SONY 1968
500510 SONY 1972
600601 COLUMBIA 1962
600602 COLUMBIA 1963
600603 ODEON 1964
670670 PHILIPS 1983
asad
You should try something like this
$result=this->db->query("select max(user_id) as maxValue form tableName")->result_array();
$maxValue=$result[0]['maxValue']; //or $result['maxValue'];
echo $maxValue;
$result2=this->db->query("select * from tableName user user_id=$maxValue")->result_array();
var_dump($result2);

Active IDs in date ranges

I have requirement to get number of customers active in a month based on their revenue contribution period.
Original Data:
ACCOUNT_ID REVENUE_START_DATE REVENUE_END_DATE
1234 1/14/2010 0:00 4/13/2010 23:59
4567 2/9/2010 0:00 3/8/2010 23:59
1234 5/9/2010 0:00 6/8/2010 23:59
Expected Result
Month Count
Dec-09 0
Jan-10 1
Feb-10 2
Mar-10 2
Apr-10 1
May-10 1
Jun-10 1
Jul-10 0
Aug-10 0
Sep-10
Oct-10
Below is the oracle code I worked on (with help of google) but I am not getting correct result due to overlapping dates. I request the experts to help me with this. (Thanks in Advance)
Current Result:
YEAR_ MONTH_ ACT
2010 January 2
2010 February 3
2010 March 3
2010 April 3
ORACLE CODE:
with tab as
(
select distinct ACCOUNT_ID, billing_start_date as revenue_start_date, billing_end_date as revenue_end_date
from accounts
),
year_tab as
(
select
add_months(min_date, level -1) m
from
(
select min(trunc(revenue_start_date,'YYYY')) min_date, add_months(max(trunc(revenue_end_date,'YYYY')), 12) max_date
from tab
)
connect by level <= months_between(max_date, min_date)
)
select to_char(m,'YYYY') year_,
to_char(m,'Month') month_,
nvl(act, 0) act
from year_tab,
(
select m date_,count(*) act
from tab, year_tab
where m between trunc(revenue_start_date,'MM') and trunc(revenue_end_date,'MM')
group by m
) month_tab
where m = date_(+)
order by m;
It's taken me a while to see why you think there is a problem. With the original three rows of data you supplied, running your query gives exactly your 'expected result'. With the 54 rows of data from your CSV file, the result is 48 rows (covering four years), with non-zero totals from January 2010 to January 2013. The first few rows returned are:
YEAR_ MONTH_ ACT
----- ------------------------------------ ----------
2010 January 2
2010 February 3
2010 March 3
2010 April 3
2010 May 2
But that looks correct:
select * from accounts
where not (billing_start_date > date '2010-02-01'
or billing_end_date < date '2010-01-01');
ACCOUNT_ID BILLING_START_DATE BILLING_END_DATE
---------- ------------------ ------------------
1234 09/01/2010 00:00 08/02/2010 23:59
4567 14/01/2010 00:00 13/04/2010 23:59
2 rows selected
select * from accounts
where not (billing_start_date > date '2010-03-01'
or billing_end_date < date '2010-02-01');
ACCOUNT_ID BILLING_START_DATE BILLING_END_DATE
---------- ------------------ ------------------
1234 09/01/2010 00:00 08/02/2010 23:59
4567 14/01/2010 00:00 13/04/2010 23:59
1234 09/02/2010 00:00 08/03/2010 23:59
3 rows selected
select * from accounts
where not (billing_start_date > date '2010-04-01'
or billing_end_date < date '2010-03-01');
ACCOUNT_ID BILLING_START_DATE BILLING_END_DATE
---------- ------------------ ------------------
4567 14/01/2010 00:00 13/04/2010 23:59
1234 09/02/2010 00:00 08/03/2010 23:59
1234 09/03/2010 00:00 08/04/2010 23:59
3 rows selected
But what I think you wanted wasn't really stressed in the question: 'to get number of customers active'. Assuming that by 'customer' you mean unique account IDs, you just need to modify the count:
select m date_,count(distinct account_id) act
from tab, year_tab
...
... which gives the first few rows as:
YEAR_ MONTH_ ACT
----- ------------------------------------ ----------
2010 January 2
2010 February 2
2010 March 2
2010 April 2
2010 May 1
What you were doing wrong was trying to apply the distinct in your tab subquery; but distinct returns distinct rows, and as the dates were different that wasn't actually reducing the number of rows returned.
Which doesn't quite match your expected result still, but does seem to match the data (if my assumption about what you want is right), and still does give your expected result for you three-row sample.
Another way to write the query, which I find a bit easier to follow, and using ANSI join syntax:
with t as (
select add_months(min_date, level - 1) month_start,
add_months(min_date, level) next_month_start
from (
select trunc(min(billing_start_date),'YYYY') min_date,
add_months(trunc(max(billing_start_date),'YYYY'), 12) max_date
from accounts
)
connect by level <= months_between(max_date, min_date)
)
select to_char(t.month_start,'YYYY') year_,
to_char(t.month_start,'Month') month_,
count(distinct a.account_id) act
from t
left join accounts a on not (billing_start_date > t.next_month_start
or billing_end_date < t.month_start)
group by t.month_start
order by t.month_start;

Resources