Background...
As part of existing data conversion we need to convert to populate Adhoc Hierarchies with a limited information.
Currently we have a finger countable members from CXO House treated to be users of this Adhoc Hierarchies.
They have their choice of Employee Hierarchical combinations for a purpose.
These hierarchies have only Parent - Child relation and can be of at any level to any level of Org Hierarchy.
In the other words... child never become a parent unless he has subordinates for him.
We have an employee table of ORG EmpHierarchy (OH) that has Organizational hierarchies.
But, which can't be directly used but we can take help of these columns to form our logic. This table is no way related to current model.
We have a few other tables HeadofDepartment(HOD), HierarchyDetails(HD) and a Stage Table same as HD.
OrgEmpHierarchy (OH) Has:
OH_ID - Organizational HierarchyID (DB Sequence)
OH_PID - (Parent ID) one of the values from previous column.
OH_EmpID - Organizational EmpID.
HeadofDepartment (HOD) Has:
HOD_ID - Head of Dept. ID (DB Sequence)
HOD_EmpID - Organizational EmpID.
HierarchyDetails (HD) Has:
HD_ID - Hierarchy Details ID (DB Sequence)
HD_PID - (ParentID) of of the values from previous column.
HD_HOD_ID - (Foreign Key) HOD_ID from HOD.
HD_EmpID - Organizational EmpID.
We need to populate the Hierarchy for each HOD_ID from Head of Department (HOD) in Hierarchy Details (HD) table.
We are able to populate values in HD for HD_ID, HD_HOD_ID, HD_Emp_ID. HD_PID is populated with NULL.
Now with the help of OH, HOD I need to populate Hierarchies in HD_PID in HD table.
Can some one give me a Oracle SQL/ PLSQL query which udpates the HD_PID?
Since this is an assignment I am not going to "give you the SQL".
You will need to use a hierarchical query which has the basic format:
SELECT some_columns
FROM a_table
START WITH some_condition
CONNECT BY PRIOR some_column = some_other_column
So, which table to select from? Well, looking at your tables OrgEmpHierarchy has contains a relationship between OH_PID (the Parent ID) and OH_EmpID so you should be using this table and connecting on those columns.
So, what should you start with? Without any data, it is difficult to say but presumably the top of the hierarchy is either an Owner/Director or the Head of Departments - if it is that latter case then you can look at starting with those employees that are IN the HeadofDepartment table.
What to select?
You're using the OH_PID and OH_EmpID columns to connect the query so you can select these as they define the hierarchical relationship.
You can select a sequence using ROWNUM or use an actual sequence YOUR_SEQUENCE.NEXTVAL.
You need to know the Head of Department - assuming you start the hierarchy at with those head of departments then there is a very simple operator that lets you "connect by the root" of the hierarchy - I'm sure a simple web search will inform you of its syntax an usage.
That just about covers it all except you'll want to insert it into a table. So, use:
INSERT INTO HierarchyDetails ( columns )
SELECT ...
Related
Let's assume I am building the backend of a university management software.
I have a users table with the following columns:
id
name
birthday
last_english_grade
last_it_grade
profs table columns:
id
name
birthday
I'd like to have a third table with which I can determine all professors teaching a student.
So I'd like to assign multiple teachers to each student.
Those Professors may change any time.
New students may be added any time too.
What's the best way to achieve this?
The canonical way to do this would be to introduce a third junction table, which exists mainly to relate users to professors:
users_profs (
user_id,
prof_id,
PRIMARY KEY (user_id, prof_id)
)
The primary key of this junction table is the combination of a user and professor ID. Note that this table is fairly lean, and avoids the problem of repeating metadata for a given user or professor. Rather, user/professor information remains in your two original tables, and does not get repeated.
I looked for this and did not find a solution that would apply to my scenario.
I'm building a database of game devs and I wish to generate a connections table:
I have the following:
Employee
(
name, date of birth, department they work at, task they do
)
Department
(
department name
)
Task
(
task name
)
and I need to generate a connections table that shows which department contributes to which task. I would do that by checking for each employee their department (only one) and task (also only one) and upon a match, the department contributes to that task.
That is the idea but I have to clue how to code it using Oracle
SELECT DISTINCT "department they work at", "task they do"
FROM Employee;
You should first work out an entity-relationship diagram, that lists the entities you use and with what attributes (and which primary keys), and the relations between those entities. Relationships can be: 1-to-1, 1-to-many and many-to-1, and many-to-many.
In the last case (M:N relation), the implementation in database tables requires an extra table to record such a M:N relationship.
The way to implement a 1:N relationship in a table is adding a foreign key in the child table to the primary key of the parent table.
EDIT: I see that you now supplied some details, and it is clear now that EMPLOYEE table is in fact the connection table, so you could simply query that table and show the DEPTID and TASKID (both the primary keys of their respective tables) to have a connection between departments and tasks. See the query in the other answer, and just add an ORDERBY on DEPTID, to show results in the order of DEPTID.
I have a report I am trying to make that displays parent information and all children in one household on ONE row.
There is no "parent" table that stores the information on parents and there is no ID that links parents to child and no ID that links sibling to sibling. The only way to tell if they are siblings is if they have the same address (logic being that if they have the same address, they live together, and are part of the same household). All the information is pulled from a "student" table or a custom field in the student table that stores the parent information, address they live at, etc.
Instead of displaying parent info twice I want to display
the information like this:
Parent_name, address, phone,child1_name, child1_schoolname, child1_age, child2_name, child2_schoolname, child2_age, etc(for every child in that household)
The problem is that not every household will have the same amount of children and I can only link siblings by their address.
How can I display all information for each household on ONE row? Is this possible and how? I've tried pivot table but with no avail.
This is a classic 'you shouldn't be doing reports in the database' question. A database is for data retrieval, not data formatting. But let's assume you know this and need to do it anyway for some reason.
The algorithm I'd use for this would be
Create some windowed queries across the data; group by address (the joinable value) and sort by age desc.
Create a query that utilize this window and returns the first item in each group.
Create additional queries that return the second, the third, the fourth, in each group. etc.
Outer join these together.
This is going to be far easier if you define some maximum number of siblings (five?) as opposed to dynamically building these siblings.
If the parents are in the same table, how do you know which items are parents and which are children?
In case you have two tables one for Parent(first table) and one for Children(second table) as below:
You can do something like that in your data model:
select Parent.NAME as parent_name,
Parent.ADDRESS as parent_address,
Parent.PHONE AS phone,
(
select listagg(Child.NAME,',')
within group(order by Child.NAME)
from CHILD Child
where Child.ADDRESS=Parent.ADDRESS
)as children_names,
(
select
listagg(Child.AGE,',')
within group(order by Child.NAME)
from CHILD Child
where Child.ADDRESS=Parent.ADDRESS
)as children_ages
from PARENT Parent .
And you will have the output query result:
Listagg is your solution which operates as you want bringing muliple rows in one.
However,listagg is compatible for database 11g and newest versions,
so in case you have older version,this is not going to work.
Hope this help.
I am having a tough time figuring out how I am supposed to implement parent-child relationships between my measure groups in SSAS. Essentially I am just trying recreate a standard SQL join so that I can lookup measures in my Parent group while using keys in my Child group.
For example, let's say I have the following dimensions:
Parent
Child (FK: ParentID)
Time
And I have the following measure groups
ParentFact (Keys: ParentID, TimeID - Measures Related to the parent over time)
ChildFact (Keys: ChildID, TimeID - Measures related to the child over time)
I have not created any specific dimensions for any of my fact tables.
In the end I just want to run a query like this to list out measures in my Child table joined to measures in my Parent table:
SELECT
{
[ChildMeasure]
, [ParentMeasure]
} ON COLUMNS
, [Child].Children ON ROWS
FROM
[MyCube]
WHERE
[Time].[100]
When this query runs, the Child rows are correctly listed, alongside the appropriate measure values for Time ID 100. Unfortunately, ParentMeasure is all the same, and appears to be an aggregate for this value over all Parents at Time ID 100. I would expect this column to show the value from each child's associated parent at Time ID 100.
What am I doing wrong here? Do I need to create FactDimensions for each FactTable, and somehow relate those? Should I crate an association between Parent and Child in my Datasource view? Would that make it a Snowflake schema, which I think I am supposed to avoid?
As a side note, my ChildFact table actually contains ParentID as one of the measures, because it is on the relational table in the datasource (probably due to some previous denormalization effort by the DB developer). Should I remove any measures that are actually FKs in my fact table, or is that somehow required for what I am trying to do?
I don't think you should attempt to create a single Fact table due to the obvious granularity issue.
I think you should add a Dimension Relationship in your Cube definition, between your Child Fact and Parent Dimension, using the existing FK column.
Probably the only valid use of ParentID as a Measure would be to get a Distinct Count.
There is no need to create two facts here.
Create a single Fact table (ParentID, ChildID, TimeID)
Create 3 dimension DimParent, DimChild, DimTime
FK of Fact table will refer to respective dimension table
Also, check the Attribute relationship how Facts are sliced with dimension
I have some tables that benefit from many-to-many tables. For example the team table.
Team member can hold more than one 'position' in the team, all the positions are listed in the position db table. The previous positions held are also stored for this I have a separate table, so I have
member table (containing team details)
positions table (containing positions)
member_to_positions table (id of member and id of position)
member_to_previous_positions (id of member and id of position)
Simple, however the crux comes now that a team member can belong to many teams aghhh.
I already have a team_to_member look-up table.
Now the problem comes how do I tie a position to a team? A member may have been team leader on one team, and is currently team radio man and press officer on a different team. How do I just pull the info per member to show his current position, but also his past history including past teams.
Do I need to add a position_to team table and somehow cross reference that, or can I add the team to the member to positions table?
It's all very confusing, this normalization.
Yes, a many-to-many junction table can have additional attributes (columns).
For example, if there's a table called PassengerFlight table that's keyed by PassengerID and FlightID, there could be a third column showing the status of the given passenger on the given flight. Two different statuses might be "confirmed" and "wait listed", each of them coded somehow.
In addition, there can be ternary relationships, relationships that involve three entities and not just two. These tables are going to have three foreign keys that taken together are the primary key for the relationship table.
It's perfectly legitimate to have a TeamPositionMember table, with the columns
Team_Id
Position_Code
Member_Id
Start_Date
End_Date NULLABLE
And and a surrogate ID column for Primary Key if you want; otherwise it's a 3-field composite Primary Key. (You'll want a uniqueness constraint on this anyway.)
With this arrangement, you can have a team with any set of positions. A team can have zero or more persons per position. A person can fill zero or more positions for zero or more teams.
EDIT:
If you want dates, just revise as shown above, and add Start_Date to the PK to allow the same person to hold the same position at different times.
My first thought:
Give your many-to-many teams/members table an ID column. Every team-to-member relationship now has an ID.
Then create a many-to-many linking positions to team-member relationships.
This way, teams can have multiple members, members can have multiple teams, and members can have multiple positions on a per-team basis.
Now everything is nice and DRY, and all the linking up seems to work. Does that sound right to anyone else?
Sounds like you need a many-to-many positions to teams table now.
Your team_to_member table can indeed have an extra column position_id to describe (or in this case point to) the position the member has within that team.
Get rid of member_to_previous_position table. Just use member_to_positions and have these columns:
MemberToPositionID (autoincrement OK only)
MemberID
PositionID
StartDate
EndDate
Then to find current positions, you do:
select *
from member_to_positions
where EndDate is null