kettle / auto-referencing table - oracle

I have an excel sheet with poeple, each people has a father and a mother that is in the same poeple sheet. My exel table looks like that :
poeple --- father --- mother
john -------- tony ----- jane
tony -------- jack
I would like to import the datas to an Oracle database table that look like :
id --- poeple --- father --- mother
0 -----jack
1 -----tony-------- 0
2 -----jane
what should be my workflow ?
3 ----john -------- 1-----------2

It would be easier to at least start by loading the data into a table with the surrogate ID:
people father mother
------ ------ ------
john tony jane
tony jack
Then you can add rows for the fathers and mothers not already in the "people" column:
insert into mytable (people)
( select mother from mytable
union
select father from mytable
)
minus
select people from mytable;
That will give you:
people father mother
------ ------ ------
jack
tony jack
jane
john tony jane
You can then add a surrogate ID for each row and use that instead, if you need it.

Related

Oracle Query Prevent Displayed Duplicate Record

Let's say i have a table structure like this :
ID | Name | SCHOOLNAME | CODESCHOOL
1 DARK Kindergarten 123 1
2 DARK Kindergarten 111 1
3 Knight NY University 3
4 Knight LA Senior HS 2
5 JOHN HARVARD 3
so, how to diplay all of the data above into like this :
ID | Name | SCHOOLNAME | CODESCHOOL
1 DARK Kindergarten 123 1
3 Knight NY University 3
5 JOHN HARVARD 3
my purpose is want to display data with the max of codeschool, but when i tried with my query below :
SELECT NAME, SCHOOLNAME, MAX(CODESCHOOL) FROM TABLE GROUP BY NAME, SCHOOLNAME
but the result is just like this :
ID | Name | SCHOOLNAME | CODESCHOOL
1 DARK Kindergarten 123 1
2 DARK Kindergarten 111 1
3 Knight NY University 3
4 Knight LA Senior HS 2
5 JOHN HARVARD 3
maybe it caused by the GROUP BY SCHOOLNAME, when i tried to not select SCHOOLNAME, the data displayed just like what i expected, but i need the SCHOOLNAME field for search condition in my query
hope you guys can help me out of this problem
any help will be appreciated
thanks
Using some wacky joins you can get a functional get max rows per category query.
What you essentially need to do is to join the table to itself and make sure that the joined values only contain the top values for the CODESCHOOL column.
I've also added a :schoolname parameter because you wanted to search by schoolname
Example:
SELECT
A.*
FROM
TABLE1 A
LEFT OUTER JOIN TABLE1 B ON B.NAME = A.NAME
AND B.CODESCHOOL < A.CODESCHOOL
WHERE
B.CODESCHOOL IS NULL AND
(
(A.SCHOOLNAME = :SCHOOLNAME AND :SCHOOLNAME IS NOT NULL) OR
(:SCHOOLNAME IS NULL)
);
this should create this output, note that dark has 2 outputs because it has 2 rows with the same code school which is the max in the dark "category"/name.
ID|NAME |SCHOOLNAME |CODESCHOOL
--| -----|----------------|----------
4|Knight|LA Senior HS | 2
5|JOHN |HARVARD | 3
2|DARK |Kindergarten 111| 1
1|DARK |Kindergarten 123| 1
It's not the most effective query but it should be more than good enough as a starting point.
Sidenote: I've been blatantly stealing this logic for a while from https://www.xaprb.com/blog/2007/03/14/how-to-find-the-max-row-per-group-in-sql-without-subqueries/
I am using an analytical window function ROW_NUMBER().
This will group (or partition) by NAME then select the top 1 CODESCHOOL in DESC order.
Select NAME,
SCHOOLNAME,
CODESCHOOL
From (
Select NAME,
SCHOOLNAME,
CODESCHOOL,
ROW_NUMBER() OVER (PARTITION BY NAME ORDER BY CODESCHOOL DESC) as rn
from myTable)
Where rn = 1;

Oracle LRS: Linear Referencing in Oracle

Does anybody know how to do Linear Referencing in Oracle?
I have a table with my route geometries, like
id routename geometry
-- --------- ----------
1 Mainstreet SDO_GEOMETRY
2 5th Avenue SDO_GEOMETRY
and I have a table with my events, like
id routename velocity from to
-- --------- -------- ---- ----
1 Mainstreet 75mph 0.0 52.5
2 Mainstreet 45mph 52.5 102.0
3 5th Avenue 75mph 0.0 78.0
I want to get the events as standard SDO_GEOMETRIES, like:
id routename velocity geometry
-- --------- -------- --------
1 Mainstreet 75mph SDO_GEOMETRY
2 Mainstreet 45mph SDO_GEOMETRY
3 5th Avenue 75mph SDO_GEOMETRY
In ArcGis or Geomedia it is very simple to achieve that... must be possible in Oracle I guess?

pass list values in where condition in linq for filtering the data in datatble

I have a requirement that i am having one string[] array (which is having the id values which is , separated values) and dt as datatable.
dt is having the columns called Id, empname, designation.
now i want to filter the data from the datatable where id not in (string[] values) using linq query.
for ex:
string[] ids= [2,4,6];
dt= id empname designation
---- ------- ------------
1 robert trainer
2 thomas HRA
3 John JE
4 kapil SE
5 sachin SSE
6 Rahul Manager
now i want a linq query which return my dt as:
id empname designation
---- ------- ------------
1 robert trainer
3 John JE
5 sachin SSE
You can use LINQ To DataTable:
var result = dt.AsEnumerable()
.Where(row => !ids.Contains(row.Field<string>("Id"));

Select all rows from SQL based upon existence of multiple rows (sequence numbers)

Let's say I have table data similar to the following:
123456 John Doe 1 Green 2001
234567 Jane Doe 1 Yellow 2001
234567 Jane Doe 2 Red 2001
345678 Jim Doe 1 Red 2001
What I am attempting to do is only isolate the records for Jane Doe based upon the fact that she has more than one row in this table. (More that one sequence number)
I cannot isolate based upon ID, names, colors, years, etc...
The number 1 in the sequence tells me that is the first record and I need to be able to display that record, as well as the number 2 record -- The change record.
If the table is called users, and the fields called ID, fname, lname, seq_no, color, date. How would I write the code to select only records that have more than one row in this table? For Example:
I want the query to display this only based upon the existence of the multiple rows:
234567 Jane Doe 1 Yellow 2001
234567 Jane Doe 2 Red 2001
In PL/SQL
First, to find the IDs for records with multiple rows you would use:
SELECT ID FROM table GROUP BY ID HAVING COUNT(*) > 1
So you could get all the records for all those people with
SELECT * FROM table WHERE ID IN (SELECT ID FROM table GROUP BY ID HAVING COUNT(*) > 1)
If you know that the second sequence ID will always be "2" and that the "2" record will never be deleted, you might find something like:
SELECT * FROM table WHERE ID IN (SELECT ID FROM table WHERE SequenceID = 2)
to be faster, but you better be sure the requirements are guaranteed to be met in your database (and you would want a compound index on (SequenceID, ID)).
Try something like the following. It's a single tablescan, as opposed to 2 like the others.
SELECT * FROM (
SELECT t1.*, COUNT(name) OVER (PARTITION BY name) mycount FROM TABLE t1
)
WHERE mycount >1;
INNER JOIN
JOIN:
SELECT u1.ID, u1.fname, u1.lname, u1.seq_no, u1.color, u1.date
FROM users u1 JOIN users u2 ON (u1.ID = u2.ID and u2.seq_no = 2)
WHERE:
SELECT u1.ID, u1.fname, u1.lname, u1.seq_no, u1.color, u1.date
FROM users u1, thetable u2
WHERE
u1.ID = u2.ID AND
u2.seq_no = 2
Check out the HAVING clause for a summary query. You can specify stuff like
HAVING COUNT(*) >= 2
and so forth.

Perl JOIN-like behavior in Oracle?

I have two tables, let's call them PERSON and NAME.
PERSON
person_id
dob
NAME
name_id
person_id
name
And let's say that the NAME table has data like:
name_id person_id name
1 1 Joe
2 1 Fred
3 1 Sam
4 2 Jane
5 2 Kim
I need a query (Oracle 10g) that will return
name_id names
1 Joe, Fred, Sam
2 Jane, Kim
Is there a simple way to do this?
Update:
According to the article that figs was kind enough to provide, starting in 9i you can do:
SELECT wmsys.wm_concat(dname) departments FROM dept;
For this example, the answer becomes:
SELECT name_id, wmsys.wm_concat(name) from names group by name_id
The short answer is to use a PL/SQL function. For more details, have a look in this post.

Resources