SQL output formatted in one line per entry - sql

I have a problem getting data displayed right, directly from Oracle SQL.
I have 2 tables. Medarb with entries meda_id and init and contacts with meda_id, cont_type and number.
The cont_type can be either 'MT' or 'MA'
what I get is:
init type number
aaaa MT 11111111
aaaa MA 22222222
bbbb MT 33333333
bbbb MA 44444444 and so on.
what I wanted was: (each person on one line)
aaaa mt 11111111 ma 22222222
bbbb mt 33333333 ma 44444444 and so on.
Is that possible?
The SQL is like this:
select distinct medarb.init, contacts.cont_type, contacts.number
from contacts
inner join medarb on medarb.meda_id = contacts.meda_id
order by medarb.init
Kind regards
Per

Aggregation usually helps in such situations.
SQL> with test (init, type, cnumber) as
2 (select 'aaaa', 'MT', 111 from dual union all
3 select 'aaaa', 'MA', 222 from dual union all
4 select 'bbbb', 'MT', 333 from dual union all
5 select 'bbbb', 'MA', 444 from dual
6 )
7 select init,
8 'MT' mttype,
9 max(case when type = 'MT' then cnumber end) cnum_mt,
10 'MA' matype,
11 max(case when type = 'MA' then cnumber end) cnum_ma
12 from test
13 group by init
14 order by init;
INIT MT CNUM_MT MA CNUM_MA
---- -- ---------- -- ----------
aaaa MT 111 MA 222
bbbb MT 333 MA 444
SQL>

what is the unique column combination for this join, is it init and type columns?
You can try using Oracle Pivot functions.
https://blogs.oracle.com/sql/how-to-convert-rows-to-columns-and-back-again-with-sql-aka-pivot-and-unpivot
thanks

Related

SQL needed to find if a property exists in multiple counties

I need some SQL to determine if a property exists in multiple counties.
I have a list of distinct property ids and county ids, but I'm not sure how to find if the property exists in more than one county.
TABLE: PROPERTIES
PROPERTYID
COUNTYID
12345
1111
12345
1112
23456
1111
34567
2222
In this example, I need some sql that will only show me property 12345 since it exists in both county 1111 and 1112.
I'm sure there is some easy SQL, but I can't figure it out.
Sample data:
SQL> with properties (propertyid, countryid) as
2 (select 12345, 1111 from dual union all
3 select 12345, 1112 from dual union all
4 select 23456, 1111 from dual union all
5 select 34567, 2222 from dual
6 )
Query:
7 select propertyid
8 from properties
9 group by propertyid
10 having count(distinct countryid) > 1;
PROPERTYID
----------
12345
SQL>

incorrect Oracle order calculation logic at the query level

With online qty and str qty, I'm having trouble calculating the quantity.
I tried the data computation with one record, and it worked perfectly with online qty and str qty. However, when I attempted it with several records (same items), it did not work. I need guidance on this.
I've written the following query, so if I'm wrong on how to design the select statement or if somebody is utilising the cursor approach, please give specifics.
Query :
with final_order as (
select 121212 po,11111 item ,20 sw_need,30 order_det from dual union all
select 131313 po,22222 item ,50 sw_need,30 order_det from dual union all
select 141414 po,33333 item ,50 sw_need,40 order_det from dual union all
select 151515 po,33333 item ,50 sw_need,30 order_det from dual union all
select 161616 po,44444 item ,50 sw_need,40 order_det from dual union all
select 171717 po,44444 item ,50 sw_need,5 order_det from dual)
select item,
case
when sw_need<order_det then sw_need
when sw_need>order_det then order_det-1
else 0
end online_qty,
case
when sw_need<order_det then order_det-sw_need
when sw_need>order_det then (order_det) -(order_det-1)
else 0
end str_qty
from final_order
Query results
ITEM
ONLINE_QTY
STR_QTY
11111
20
10
22222
29
1
33333
39
1
33333
29
1
44444
39
1
44444
4
1
Expected results
PO
ITEM
SW_NEED
ORDER_DET
ONLINE_QTY
STORE_QTY
121212
11111
20
30
20
10
131313
22222
50
30
29
1
141414
33333
50
40
40
0
151515
33333
50
30
10
20
1616416
44444
50
40
40
0
171717
44444
50
5
4
1

How to combine rows together where only one column is different between rows

I have a query which result in expense claims.
Sometimes the receipt attached is attached to the header level rather than the line level so the output is that the rows runs twice per expense line as it cannot map the exact receipt attachment.
How do I combine the 'receipt name' so it can aggregate in one row. I need it so I can look up the exact receipts matched to the expense line.
Please see table below.
Claimant Claim_Date Claim_Number Description Amount Receipt_Name
Name A 01/08/20 10001 Coffee £4.00 Coffee at Star.jpg
Name B 02/08/20 10002 Stationery £20.00 Stationery Receipt.jpg
Name B 02/08/20 10002 Stationery £20.00 Laptop.jpg
Name B 02/08/20 10002 Laptop Buy £600.00 Stationery Receipt.jpg
Name B 02/08/20 10002 Laptop Buy £600.00 Laptop.jpg
Name C 02/08/20 10003 Biscuits £10.00 Mcv's.jpg
Name A 02/08/20 10004 Office Wear £100.00 Suitsonline.jpg
I would like it to be
Claimant Claim_Date Claim_Number Description Amount Receipt_Name
Name A 01/08/20 10001 Coffee £4.00 Coffee at Star.jpg
Name B 02/08/20 10002 Stationery £20.00 Stationery Receipt.jpg, Laptop.jpg
Name B 02/08/20 10002 Laptop Buy £600.00 Stationery Receipt.jpg, Laptop.jpg
Name C 02/08/20 10003 Biscuits £10.00 Mcv's.jpg
Name A 02/08/20 10004 Office Wear £100.00 Suitsonline.jpg
I have tried to use LISTAGG and have tried certain group by functions.
Here is my current Query (cut down)
select claimant.display_name claimant,
expr.report_submit_date claim_date,
expr.expense_report_num claim_number,
exp.description description,
round(exp.receipt_amount * exp.exchange_rate,2) amount,
case when linefndtl.file_name IS NULL then fndtl.file_name
when fndtl.file_name IS NULL then linefndtl.file_name
when fndtl.file_name IS NULL AND linefndtl.file_name IS NULL then 'Missing'
ELSE NULL
END Expense_File_Name,
-- Main Sources
from exm_expense_reports expr
left join exm_expenses exp on exp.expense_report_id = expr.expense_report_id
left join exm_expense_dists expdist on expdist.expense_report_id = exp.expense_report_id
and expdist.expense_id = exp.expense_id
-- Claimant
left join per_person_names_f_v claimant on claimant.person_id = expr.person_id
and trunc(sysdate) between claimant.effective_start_date and claimant.effective_end_date
-- Attachment at Header
left join exm_expenses headerexmexpenses on headerexmexpenses.expense_id = exp.itemization_parent_expense_id
left join fnd_attached_documents fndad on to_char(headerexmexpenses.expense_id) = fndad.pk1_value
left join fnd_documents_tl fndtl on fndtl.document_id = fndad.document_id
-- Attachment at Line
left join fnd_attached_documents linefndad on to_char(exp.expense_id) = linefndad.pk1_value
left join fnd_documents_tl linefndtl on linefndad.document_id = linefndtl.document_id
where 1 = 1
and nvl(exp.itemization_parent_expense_id, 1) <> -1
All results are the same except the file name row.
Many thanks!
I would think that LISTAGG does the job.
TEST CTE represents your current data. Lines #11 onward show that it works.
SQL> with test (Claimant, Claim_Date, Claim_Number, Description, Amount, Receipt_Name) as
2 (select
3 'Name A', '01/08/20', 10001, 'Coffee' ,4 ,'Coffee at Star.jpg' from dual union all select
4 'Name B', '02/08/20', 10002, 'Stationery' ,20 ,'Stationery Receipt.jpg' from dual union all select
5 'Name B', '02/08/20', 10002, 'Stationery' ,20 ,'Laptop.jpg' from dual union all select
6 'Name B', '02/08/20', 10002, 'Laptop Buy' ,600 ,'Stationery Receipt.jpg' from dual union all select
7 'Name B', '02/08/20', 10002, 'Laptop Buy' ,600 ,'Laptop.jpg' from dual union all select
8 'Name C', '02/08/20', 10003, 'Biscuits' ,10 ,'Mcv''s.jpg' from dual union all select
9 'Name A', '02/08/20', 10004, 'Office Wear' ,100 ,'Suitsonline.jpg' from dual
10 )
11 select claimant, claim_date, claim_number,
12 description, amount,
13 listagg(receipt_name, ', ') within group (order by receipt_name) receipt_name
14 from test
15 group by Claimant, Claim_Date, Claim_Number, Description, Amount
16 order by claimant;
CLAIMA CLAIM_DA CLAIM_NUMBER DESCRIPTION AMOUNT RECEIPT_NAME
------ -------- ------------ ----------- ---------- ----------------------------------------
Name A 01/08/20 10001 Coffee 4 Coffee at Star.jpg
Name A 02/08/20 10004 Office Wear 100 Suitsonline.jpg
Name B 02/08/20 10002 Laptop Buy 600 Laptop.jpg, Stationery Receipt.jpg
Name B 02/08/20 10002 Stationery 20 Laptop.jpg, Stationery Receipt.jpg
Name C 02/08/20 10003 Biscuits 10 Mcv's.jpg
SQL>
The simplest way to do it is to use your current query as a CTE and apply the rest of the query (lines #11 onward, right?) to it.

update table column from view in another database in oracle sql developer

i have 2 database in oracle.
DATABASE TABLE/VIEW NAME
digidb1 CUSTOMER_REFERENCE
digidb2 CUST_REF_VIEW
this query will display all data in the table CUSTOMER_REFERENCE from db digidb1.
select * from CUSTOMER_REFERENCE
cust_id brch_code cust_name description
001 001 COMPANY TEST 1 TEST COMPANY 1
002 002 COMPANY TEST 2 TEST COMPANY 2
003 003 COMPANY TEST 3 TEST COMPANY 3
this query will display all data in the view CUST_REF_VIEW from db digidb2.
select * FROM CUST_REF_VIEW
WINBBN CUSTFULLNAME ISINDIVIDUAL MRGDATE
1234 COMPANY TEST 1 N 12-03-20
4567 COMPANY TEST 4 N 12-03-20
8901 COMPANY TEST 2 N 11-03-20
2345 COMPANY TEST 5 Y 10-03-20
6789 COMPANY TEST 3 N 12-03-20
is it possible to update the table(CUSTOMER_REFERENCE) from database(digidb1) with this data?
i want to update cust_id column in CUSTOMER_REFERENCE from digidb1. the data will come from view CUST_REF_VIEW of digidb2.
the condition for updates are:
CUSTFULLNAME is equal to cust_name
MRGDATE is equal to system date/today (12-03-20)
ISINDIVIDUAL is equal to N.
my expected result is:
cust_id brch_code cust_name description
1234 001 COMPANY TEST 1 TEST COMPANY 1
002 002 COMPANY TEST 2 TEST COMPANY 2
6789 003 COMPANY TEST 3 TEST COMPANY 3
If I understood you correctly, you don't actually want to update anything, but select data from those two views by joining them, using certain conditions. If that's so, then:
SQL> with
2 -- sample data
3 customer_reference (cust_id, brch_code, cust_name, description) as
4 (select '001', '001', 'CT1', 'TC1' from dual union all
5 select '002', '002', 'CT2', 'TC2' from dual union all
6 select '003', '003', 'CT3', 'TC3' from dual
7 ),
8 cust_ref_view (winbbn, custfullname, isindividual, mgrdate) as
9 (select '1234', 'CT1', 'N', date '2020-03-12' from dual union all
10 select '4567', 'CT4', 'N', date '2020-03-12' from dual union all
11 select '8901', 'CT2', 'N', date '2020-03-11' from dual union all
12 select '2345', 'CT5', 'Y', date '2020-03-10' from dual union all
13 select '6789', 'CT3', 'N', date '2020-03-12' from dual
14 )
15 -- query you need
16 select case when v.mgrdate = trunc(sysdate)
17 and v.isindividual = 'N'
18 then v.winbbn
19 else r.cust_id
20 end cust_id,
21 --
22 r.brch_code, r.cust_name, r.description
23 from customer_reference r join cust_ref_view v on v.custfullname = r.cust_name;
CUST BRC CUS DES
---- --- --- ---
1234 001 CT1 TC1
002 002 CT2 TC2
6789 003 CT3 TC3
SQL>
Now, depending on what you really call "database", a database link might to be be involved if those really are different databases, e.g.
from customer_reference r join cust_ref_view#db_link_digidb2 v
----------------
this
If it is just about different users (schemas) within the same database, then you'll need to grant (at least) SELECT privilege from one user to another. It also means that you'd need to precede remote view name with its owner name, e.g.
from customer_reference r join digidb2.cust_ref_view v
--------
this
or - a simpler option - to create a synonym in one schema which will point to view in another schema. In that case, line #23 in query I posted would look exactly the same.

join multiple table

i got 4 tables
table A
code accnt
-------------------
123 xxx
222 yyy
333 zzz
table B
code alloted
-----------------------
123 100
222 200
333 300
table C
code ref project
-------------------------------
333 11-2015 maintenance
table D
code ref item cost
---------------------------------------
333 11-2015 hammer 100
333 11-2015 nail 200
i want to join this table and have and output i like this
code accnt ref alloted
-----------------------------------------
123 xxx 100
222 yyy 200
333 zzz 300
333 maintenance 11-2015
333 hammer 11-2015 100
333 nail 11-2015 200
i use left join for this but i can't get the field A.accnt, C.project & D.item to be combine as one column..thanks in advance
Here is the Solution:
select tableA.code, accnt, '' as ref, alloted from tableA join tableB on tableA.code = tableB.code
Union ALL
select code, project as accnt, ref, ''as alloted from tableC
Union ALL
select code, item as accnt, ref, cost as alloted from tableD
Thanks!
Sounds like you need to JOIN the first 2 tables and UNION in the other 2.
See if this works for you --
SELECT a.code, a.accnt, NULL AS ref, b.alloted
FROM A
LEFT JOIN B ON a.code = b.code
UNION
SELECT c.code, c.project AS accnt, c.ref, NULL AS alloted
UNION
SELECT d.code, d.item AS accnt, d.ref, d.cost as alloted
UNION will take distinct results when combining. If you want ALL results, then use UNION ALL instead.
Here is an explanation that might help you understand the difference between the 2 -- JOIN combines multiple tables by appending columns based on some criteria where UNION combines multiple tables by appending rows. There are MANY tutorials out there that explain JOIN/UNION if you need more information.