How to find ID that occurs across multiple categories - oracle

hi I have a query called cte. I have to find IDs in this query that occur across multiple categories. Here are the fields available in my table:
product_owner
product_ownerid
owner_location
owner_locationid
case_id
unique_id
red
123
texas
321
12345
89076
red
123
texas
321
12345
89075
blue
456
NY
786
12678
90768
blue
456
NY
786
12678
90769
red
123
texas
321
12678
79072
in this case, 12678 exists for both red and blue category. I want to create a final table that looks like this:
product_owner
product_ownerid
owner_location
owner_locationid
case_id
unique_id
blue
456
NY
786
12678
90768
blue
456
NY
786
12678
90769
red
123
texas
321
12678
79072
I would really appreciate if someone could please help me figure out how I can achieve this. So far, this is what I have tried but it is not yielding the result that I want:
SELECT DISTINCT
cte.product_owner,
cte.product_ownerid,
cte.owner_location,
cte.owner_locationid,
cte.Case_ID,
cte.unique_id
FROM cte
JOIN (SELECT Case_ID FROM cte
GROUP BY Case_ID
HAVING count (DISTINCT unique_id) >1) y
ON cte.Case_ID = y.Case_ID
ORDER BY cte.Case_Reference_ID

Count the distinct product_ownerid for each case_id and filter out the rows where the count is only 1:
SELECT *
FROM (
SELECT t.*,
COUNT(DISTINCT product_ownerid) OVER (PARTITION BY case_id)
AS num_products
FROM cte t
)
WHERE num_products > 1
Which, for the sample data:
CREATE TABLE cte (
product_owner, product_ownerid, owner_location, owner_locationid, case_id, unique_id
) AS
SELECT 'red', 123, 'texas', 321, 12345, 89076 FROM DUAL UNION ALL
SELECT 'red', 123, 'texas', 321, 12345, 89075 FROM DUAL UNION ALL
SELECT 'blue', 456, 'NY', 786, 12678, 90768 FROM DUAL UNION ALL
SELECT 'blue', 456, 'NY', 786, 12678, 90769 FROM DUAL UNION ALL
SELECT 'red', 123, 'texas', 321, 12678, 79072 FROM DUAL;
Outputs:
PRODUCT_OWNER
PRODUCT_OWNERID
OWNER_LOCATION
OWNER_LOCATIONID
CASE_ID
UNIQUE_ID
NUM_PRODUCTS
red
123
texas
321
12678
79072
2
blue
456
NY
786
12678
90769
2
blue
456
NY
786
12678
90768
2
db<>fiddle here

Related

How to sum total amount without grouping even have duplicated number?

table_a table_b
desc amount ID vcref ID
banana 2.00 101 VC10001 101
apple 3.00 101 VC10001 101
orange 5.00 101 VC10003 101
select sum(a.amount),b.vcref from table_a a,table_b b where a.ID=b.ID group by b.vcref;
result
20.0 VC10001
10.0 VC10003
-------------------------------------------
May I know it is possible to show result like this ?
result
10.0 VC10001
10.0 VC10001
10.0 VC10003
Anyone help is much appreciated.
One option is to use a correlated subquery:
Sample data:
SQL> with
2 table_a (c_desc, amount, id) as
3 (select 'banana', 2, 101 from dual union all
4 select 'apple' , 3, 101 from dual union all
5 select 'orange', 5, 101 from dual
6 ),
7 table_b (vcref, id) as
8 (select 'vc1001', 101 from dual union all
9 select 'vc1001', 101 from dual union all
10 select 'vc1003', 101 from dual
11 )
Query:
12 select b.vcref,
13 (select sum(a.amount) from table_a a where a.id = b.id) total
14 from table_b b;
VCREF TOTAL
------ ----------
vc1001 10
vc1001 10
vc1003 10
SQL>
Select the sum as an inner query:
select
(select sum(amount) from table_a) as result,
vcref
from table_b

How to achieve string concatentation of entries in column having same id in Oracle Analytics Cloud Professional Edition?

I have a dataset in which one column is Branch-ID and other one is Branch Manager and it looks as follows in the given url.
dataset
I want to combine the branch managers into one single column based on the branch-id. For example if Bob and Sandra are two different branch-managers but have the same branch id which is branch-id=1, then we should concatenate them together as Bob-Sandra and place them in a separately created column.
I have attached the expected output for the above dataset. expected_output_dataset
I am currently using Oracle Analytics Cloud Professional Version.
I don't know Oracle Analytics, but - if it has anything to do with an Oracle database and its capabilities, then listagg helps.
Sample data in lines #1 - 10; query you might be interested in begins at line #11.
SQL> with test (account_id, branch_id, branch_manager) as
2 (select 1, 123, 'Sandra' from dual union all
3 select 3, 124, 'Martha' from dual union all
4 select 4, 125, 'John' from dual union all
5 select 6, 126, 'Andrew' from dual union all
6 select 7, 126, 'Mathew' from dual union all
7 select 2, 123, 'Michael' from dual union all
8 select 5, 125, 'David' from dual union all
9 select 8, 126, 'Mark' from dual
10 )
11 select a.account_id, a.branch_id, a.branch_manager,
12 b.concatenated_column
13 from test a join (select branch_id,
14 listagg(branch_manager, '-') within group (order by null) concatenated_column
15 from test
16 group by branch_id
17 ) b on b.branch_id = a.branch_id;
ACCOUNT_ID BRANCH_ID BRANCH_ CONCATENATED_COLUMN
---------- ---------- ------- -------------------------
1 123 Sandra Michael-Sandra
3 124 Martha Martha
4 125 John David-John
6 126 Andrew Andrew-Mark-Mathew
7 126 Mathew Andrew-Mark-Mathew
2 123 Michael Michael-Sandra
5 125 David David-John
8 126 Mark Andrew-Mark-Mathew
8 rows selected.
SQL>

how to write query to display two rows in one row from same table with different alias column names using oracle

i need to display two rows from same table with different column names. one as Current columns and other as previous columns. How to display it in one row.
SELECT BILL_ID CUR_BILL_ID, BILL_START_DT CUR_BILL_START_DT, BILL_END_DT CUR_BILL_END_DT, BILL_STATUS_CD CUR_BILL_STATUS_CD, BILL_APPROVED_BY CUR_BILL_APPROVED_BY, BILL_APPROVED_DT CUR_BILL_APPROVED_DT FROM FPM_CB_BILL_DETAILS WHERE BILL_ID = (select max(BILL_ID) from FPM_CB_BILL_DETAILS)
SELECT BILL_ID PRV_BILL_ID, BILL_START_DT PRV_BILL_START_DT, BILL_END_DT PRV_BILL_END_DT, BILL_STATUS_CD PRV_BILL_STATUS_CD, BILL_APPROVED_BY PRV_BILL_APPROVED_BY, BILL_APPROVED_DT PRV_BILL_APPROVED_DT FROM FPM_CB_BILL_DETAILS WHERE BILL_ID = (select max(BILL_ID) from FPM_CB_BILL_DETAILS) - 1
Looks like selfjoin might help.
SQL> with fpm_cb_bill_Details (bill_id, bill_status_cd) as
2 (select 100, 'status A' from dual union all
3 select 101, 'status B' from dual union all
4 select 102, 'statuc C' from dual union all
5 select 103, 'status D' from dual
6 )
7 select a.bill_id curr_bill_id,
8 a.bill_status_cd curr_status,
9 b.bill_id prev_bill_id,
10 b.bill_status_cd prev_status
11 from fpm_cb_bill_details a join fpm_cb_bill_details b on b.bill_id = a.bill_id - 1
12 where a.bill_id = (select max(bill_id) from fpm_cb_bill_details);
CURR_BILL_ID CURR_STA PREV_BILL_ID PREV_STA
------------ -------- ------------ --------
103 status D 102 statuc C
SQL>
You can use lag() analytic function to see the previous row's column values, ordering by bill_id as follows:
FSITJA#db01> with fpm_cb_bill_Details (bill_id, bill_status_cd) as
2 (select 100, 'status A' from dual union all
3 select 101, 'status B' from dual union all
4 select 102, 'statuc C' from dual union all
5 select 103, 'status D' from dual
6 )
7 select d.bill_id curr_bill_id,
8 d.bill_status_cd curr_status,
9 lag(d.bill_id) over (order by d.bill_id) prev_bill_id,
10 lag(d.bill_status_cd) over (order by d.bill_id) prev_status
11 from fpm_cb_bill_Details d;
CURR_BILL_ID CURR_STA PREV_BILL_ID PREV_STA
------------ -------- ------------ --------
100 status A
101 status B 100 status A
102 statuc C 101 status B
103 status D 102 statuc C
Thanks #Littlefoot for the sample table data.

Oracle - select statement to pivot and change how data is displayed

I currently have data in an Oracle tabel that looks like this:
Person_ID Fieldname Fieldnumber
123 2016 Salary 50000
123 2015 Salary 45000
123 2014 Salary 40000
123 2016 Vacation Days 5
456 2016 Salary 50000
456 2016 Vacation Days 5
789 2016 Salary 90000
789 2016 Vacation Days 5
I would like write a select statement to Pivot and change the display of the data so it looks like this:
Person_ID Fieldname 2016 2015 2014
123 Salary 55000 45000 40000
123 Vacation Days 5
456 Salary 50000
456 Vacation Days 5
789 Salary 90000
789 Salary 5
How can I do this so that if new field names are added, my SQL will automatically add new columns when I run it? Is there a way to do this with pivot or should I use union or another function that I am not familiar with?
The pivot I usually run looks like this but I don't think the concept will work in this scenario:
select *
from cust_matrix
unpivot
(
state_counts
for state_code in ("New York","Conn","New Jersey","Florida","Missouri")
)
order by "Puchase Frequency", state_code
Thank you
Don't be confused by the fact that there are two columns that are not part of the "pivot", in your case person_id and fieldname. Pivoting works exactly the same way.
Notes - your input table is obviously missing a column name (for year) - which better not be Year, a reserved word in Oracle. I used yr in my sample inputs. You also have a typo in the output (where did 55000 come from, for year 2016 and person_id = 123? The inputs had 50000).
And, you can have 2016 as a column name, but it would have to be double-quoted and it may cause unexpected problems later. Best to use standard column names - which, in particular, can't begin with a digit. I used y2016 etc.
with
inputs ( person_id, yr, fieldname, fieldnumber ) as (
select 123, 2016, 'Salary' , 50000 from dual union all
select 123, 2015, 'Salary' , 45000 from dual union all
select 123, 2014, 'Salary' , 40000 from dual union all
select 123, 2016, 'Vacation Days', 5 from dual union all
select 456, 2016, 'Salary' , 50000 from dual union all
select 456, 2016, 'Vacation Days', 5 from dual union all
select 789, 2016, 'Salary' , 90000 from dual union all
select 789, 2016, 'Vacation Days', 5 from dual
)
-- end of test data; actual solution (SQL query) begins below this line
select person_id, fieldname, y2016, y2015, y2014
from inputs
pivot ( max(fieldnumber) for yr in (2016 as y2016, 2015 as y2015, 2014 as y2014) )
order by person_id, fieldname
;
PERSON_ID FIELDNAME Y2016 Y2015 Y2014
--------- ------------- ----- ----- -----
123 Salary 50000 45000 40000
123 Vacation Days 5
456 Salary 50000
456 Vacation Days 5
789 Salary 90000
789 Vacation Days 5

Combining column values from different tables

I stuck. I have 2 tables - look at image no.1 Table columns And i would like to build query, that will give me the result - it is showed on image no 2. the result of query.
I have 2 queries and I would like to mix them up, to obtain the list from image no.2. Please help me, how to build a query.
Query no1: SELECT department_name, department_id FROM DEPARTMENTS WHERE department_id between 90 AND 110;
Query no 2: SELECT last_name, department_id from employees WHERE department_id between 90 AND 110;
Query:
with departments (department_id, department_name) as (
select 90, 'Executive' from dual union all
select 100, 'Finance' from dual union all
select 110, 'Accounting' from dual
),
employees (employee_id, last_name, department_id) as (
select 1003, 'King' , 90 from dual union all
select 1005, 'De Hann' , 90 from dual union all
select 1009, 'Gietz' , 110 from dual union all
select 1013, 'Popp' , 100 from dual union all
select 1014, 'Chen' , 100 from dual union all
select 1015, 'Higgins' , 110 from dual union all
select 1029, 'Greenberg', 100 from dual union all
select 1040, 'Kochar' , 90 from dual union all
select 1043, 'Faviet' , 100 from dual union all
select 1045, 'Urman' , 100 from dual union all
select 1049, 'Sciarra' , 100 from dual
)
-- end input data; begin actual query --
select c_name, department_id from
( select department_name as c_name, department_id, 0 as categ from departments
union all
select ' ' || last_name as c_name, department_id, 1 from employees
order by department_id, categ, c_name
);
Result:
C_NAME DEPARTMENT_ID
------------- -------------
Executive 90
De Hann 90
King 90
Kochar 90
Finance 100
Chen 100
Faviet 100
Greenberg 100
Popp 100
Sciarra 100
Urman 100
Accounting 110
Gietz 110
Higgins 110
You don't need the "with ..." part; just use the query that begins at the SELECT statement after the two factored subqueries (after the "input data"). I even ordered by last name within each department for you; if that is not needed, just delete "c_name" from the ORDER BY clause.
I called the first column c_name; you may call it whatever you want, but calling it department_name when it also holds employee last names didn't make much sense to me. To call it whatever you want, change the SELECT statement from SELECT c_name, department_id to SELECT c_name AS whatever, department_id...
SELECT c.last_name,
d.department_id,
d.department_name
FROM employee c
JOIN deptartment d ON d.department_id=c.department_id
WHERE d.department_id BETWEEN 90 AN 110
OUTPUT from my sample table
+-------+----+------------+
| KING | 10 | ACCOUNTING |
| BLAKE | 30 | SALES |
| CLARK | 10 | ACCOUNTING |
| JONES | 20 | RESEARCH |
| SCOTT | 20 | RESEARCH |
+-------+----+------------+

Resources