SQL getting multiple rows in PARTICULAR sql - sql

I have a table abc with following rows:
emp_id_role Group_name Role_name Location_id
12 Insurance Manager Noida
12 Insurance Senior Manager Noida
13 Global Client Services Sw UP
14 Operations Management All Jobs kERALA
and another master table with all the details employee_xyz:
PERSON_ID NAME DOB START_DATE END_DATE SSN
12 DEAN 01-JAN-1990 01-JAN-2017 20-JAN-2017 847474
12 DEAN 01-JAN-1990 21-JAN-2017 03-mar-2018 847474
12 DEAN 01-JAN-1990 04-mar2018 31-DEC-4712 847474
13 SAM 20-JAN-1990 17-JAN-2016 20-JAN-2017 847474
13 SAM 20-JAN-1990 21-JAN-2017 31-DEC-4712 847474
14 JAY 29-dec-1990 21-JAN-2016 31-DEC-4712 847474
I want to fetch the full names from the table employee_xyz for the records in table abc.
When I'm joining these two using the below queries I'm getting more number of rows for an employee than in table abc,
Eg: for employee_id 12 I should get 2 rows as in table abc but I'm getting 9 rows somehow...
Query used is simple :
select * from table_abc abc,
employee_xyz xyz
where xyz.person_id=abc.emp_id_role
and trunc(sysdate) between abc.Start_date and xyz.end_date
and person_id=12;

I suppose you want to select all columns from table_abc with names from employee_xyz.
If your try with select abc.*, xyz.name, you already able to select as two rows since sysdate for person_id= 12 stays in the interval only for third row(start_date:04-mar2018/ end_date:31-DEC-4712) but if you want non-repeating even with more date values stay, you can use distinct : select distinct abc.*, xyz.name as below( where there're two rows in the interval second row's end date converted from '2018-03-03' to '2019-03-03' ) :
with table_abc(emp_id_role, Group_name, Role_name, Location_id) as
(
select 12,'Insurance','Manager','Noida' from dual union all
select 12,'Insurance','Senior Manager','Noida' from dual union all
select 13,'Global Client Services','Sw', 'UP' from dual union all
select 14,'Operations Management','All Jobs','kERALA' from dual
),
employee_xyz(person_id,name, dob, start_date, end_date, ssn) as
(
select 12,'DEAN',date'1990-01-01',date'2017-01-01',date'2017-01-20',847474 from dual union all
select 12,'DEAN',date'1990-01-01',date'2017-01-21',date'2019-03-03',847474 from dual union all
select 12,'DEAN',date'1990-01-01',date'2018-03-04',date'4712-12-31',847474 from dual
)
select distinct abc.*, xyz.name
from table_abc abc join employee_xyz xyz
on xyz.person_id = abc.emp_id_role
where trunc(sysdate) between xyz.Start_date and xyz.end_date
and person_id = 12;
EMP_ID_ROLE GROUP_NAME ROLE_NAME LOCATION_ID NAME
----------- ---------- --------------- ----------- -----
12 Insurance Manager Noida DEAN
12 Insurance Senior Manager Noida DEAN

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>

How to find all records that are older than or equal to the current month of the previous year?

I barely know SQL. I am trying to achieve the following:
For example I have the following table that has 2 fields
NAME VARCHAR(20)
BDAY TIMESTAMP(6)
I need to find all whose birthdays are current month of the previous year and prior. For example if I am running the query on 08/15/2021, I need to find all records that have a month/date of 08/2020 (ignoring the day part) and prior. So some entries may be less than 12 months old (those after the day of query in the current month of prior year) and would get need to get included in the returned rows.
if I have the following records and I am running the query on 8/15/2021
Mark 12/22/2018
Mike 10/15/2019
Joe 07/31/2020
John 08/06/2020
Jill 08/28/2020
Bill 08/31/2020
Jack 09/01/2020
Jeb 08/08/2021
It needs to return the following:
Mark 12/22/2018
Mike 10/15/2019
Joe 07/31/2020
John 08/06/2020
Jill 08/28/2020
Bill 08/31/2020
If I did something like the following,
select * from BDAY where BDAY < add_months(systimestamp,-12) order by BDAY desc;
it would exclude the entries for the current month of previous year that are after the date when the query is run. I can get the desired result using convoluted queries but I was wondering if there was an easier way of doing this, e.g. an oracle function.
You can compare with the first day of next month, ie 11 months ago instead of 12:
select * from bday where bday<trunc(add_months(sysdate ,-11), 'mm');
Full example with test data:
alter session set nls_date_format='mm/dd/yyyy';
with bday(name, bday) as (
select 'Mark',to_date('12/22/2018','mm/dd/yyyy') from dual union all
select 'Mike',to_date('10/15/2019','mm/dd/yyyy') from dual union all
select 'Joe ',to_date('07/31/2020','mm/dd/yyyy') from dual union all
select 'John',to_date('08/06/2020','mm/dd/yyyy') from dual union all
select 'Jill',to_date('08/28/2020','mm/dd/yyyy') from dual union all
select 'Bill',to_date('08/31/2020','mm/dd/yyyy') from dual union all
select 'Jack',to_date('09/01/2020','mm/dd/yyyy') from dual union all
select 'Jeb ',to_date('08/08/2021','mm/dd/yyyy') from dual
)
select * from bday where bday<trunc(add_months(sysdate ,-11), 'mm');
NAME BDAY
---- ----------
Mark 12/22/2018
Mike 10/15/2019
Joe 07/31/2020
John 08/06/2020
Jill 08/28/2020
Bill 08/31/2020
6 rows selected.
DBFIDDLE: https://dbfiddle.uk/?rdbms=oracle_18&fiddle=b9f4889a47f59f6a48d3fb2d0a212617

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.

t/sql query with two different tables

i need to create an oracle select statement that returns acct,name,city,splitcost from table1 and APIcost from table2. table1 splits the 90 into 3 diff. amounts because they are distributed elsewhere. table2 is the API download that only has 1 record of the total 90. if i use inner join the 90 repeats on each row linking by acct. i need the results to look like the second view only show APIcost total 90. once per acct.
hope this makes sense. if i was using sql I'm prob. do a temp table but it has to be done in Oracle which i'm not used too.
No need for a temp table, just build a rank and do a case statement on it to populate the first row with the api_cost. I don't know which row you want, so play with the "order by" clause to get that to do the row you want.
/* Building out your data to a "temp table" */
with table1 as
(select 1111 as acct, 'john' as name, 'hampton' as city, 30 as split_cost, 90 as
api_cost from dual union all
select 1111 as acct, 'john' as name, 'hampton' as city, 40 as split_cost, 90 as
api_cost from dual union all
select 1111 as acct, 'john' as name, 'hampton' as city, 20 as split_cost, 90 as
api_cost from dual union all
select 1111 as acct, 'john' as name, 'hampton' as city, 20 as split_cost, 90 as
api_cost from dual)
/* You need nothing above here, just below */
select acct, name, city, split_cost,
case when rank() over (partition by acct, name, city order by split_cost, rownum) =
1 then api_cost
else null
end as api_cost
from table1; --substitute your table name here
OUTPUT:
ACCT NAME CITY SPLIT_COST API_COST
1111 john hampton 20 90
1111 john hampton 20
1111 john hampton 30
1111 john hampton 40

Updating a table in Oracle based on data from another table and 3 keys

All,
Here is my two tables:
Table customer
First_Name | Last_Name | Purchases| Age
John Rambo 10 55
George Washington 17 99
Eli Manning 7 35
Table client
First_Name | Last_Name | Purchases| Client_Id | Date_Added
John Rambo 10 4 12-mar-2016
George Washington 17 6 20-jan-2016
Eli Manning 7 3 10-dec-2016
Jerry Seinfeld 4 3 19-mar-2016
Desired result
Table customer:
First_Name | Last_Name | Purchases| Age | Client_Id | Date_Added
John Rambo 10 55 4 12-mar-2016
George Washington 17 99 6 20-jan-2016
Eli Manning 7 35 3 10-dec-2016
I want to add Client_Id and Date_Added to customer. Lets say I added those columns and now have to devise the update statement. The conditions are if First_Name or Last_Name or Purchases match in both tables, populate customer. Lets just say for arguments sake these fields will always be unique so we just need one to match. How would you do this in oracle? Mind you this would be done for a couple hundred thousand records.
With all your assumptions, saying that you already added the needed columns, you may need a MERGE.
setup:
create table sustomer(First_Name , Last_Name , Purchases, Age) as (
select 'John' , 'Rambo' , 10 , 55 from dual union all
select 'George' , 'Washington' , 17 , 99 from dual union all
select 'Eli' , 'Manning' , 7 , 35 from dual
);
create Table client(First_Name , Last_Name ,Purchases,Client_Id ,Date_Added) as (
select 'John' ,'Rambo' , 10 , 4 , to_date('12-03-2016','dd-mm-yyyy') from dual union all
select 'George' ,'Washington' , 17 , 6 , to_date('20-01-2016','dd-mm-yyyy') from dual union all
select 'Eli' ,'Manning' , 7 , 3 , to_date('10-12-2016','dd-mm-yyyy') from dual union all
select 'Jerry' ,'Seinfeld' , 4 , 3 , to_date('19-03-2016','dd-mm-yyyy') from dual
);
alter table customer add Date_Added date;
alter table customer add Client_Id number;
MERGE:
merge into customer cu
using ( select * from client) cl
on ( cl.First_Name = cu.First_Name OR
cl.Last_Name = cu.Last_Name OR
cl.Purchases = cu.Purchases
)
when matched then
update set Date_Added = cl.Date_Added,
Client_Id = cl.Client_Id
This gives, on your data:
FIRST_ LAST_NAME PURCHASES AGE CLIENT_ID DATE_ADDE
------ ---------- ---------- ---------- ---------- ---------
John Rambo 10 55 4 12-MAR-16
George Washington 17 99 6 20-GEN-16
Eli Manning 7 35 3 10-DEC-16