Modeling variable depth inheritance in MySQL - mysql

I am working on a project where I need to have data inherit at variable depths, and then be able to return any descendants of a particular piece of data. I am working with geographical regions, so I was thinking about having a "Region" table, and have everything from "North America" to individual neighborhoods such as "Bronx". So, if someone types in "North America", they should also receive results for "Bronx" because "Bronx" is a descendant of "North America" by means of the relationship
North America->United States->New York(State)->New York(City)->Bronx
In my DB I was planning on having the Region table link back to itself with a table that specifies a parent/child relationship between Regions. Here is an example of what I would propose:
Any help would be greatly appreciated!

Do you dont need a new table. A foreign key in major table is enough.
This is my approach:
First problem, design data schema: I keep hierarchis with a foreign key to parent row. It is simply. You have an example with hiererchy regions here:
WOE_ID ISO Name Language PlaceType Parent_ID
20069843 "NA" "Oshana" ENG State 23424987
55921113 "NA" "Ondangwa" ENG County 20069843
...
Second problem, retrieve ascendants/descendants: As you explain, problems comes with select: select some region and all descendants os ascendants. To solve this you should to create a new tree table. This table contains pairs: al combination to a person with all they ancestors (and itself):
region( id, name, id_parent)
region_tree( id, id_ancestor, distance )
Noticie that with this structure is easy to query hierarchies. Sample: all descendants of some region:
select region.*, distance
from
region p
inner join
region_tree t
on ( p.id = t.id)
where
id_ancesor = **someregion.id **
You can play with distance to get only sub-regions, sub-sub-regions, ...
Last problem, keep tree: tree must be all time up to data. You should automatize this: a trigger over region or a store procedure for CRUD operations,

Related

Making a Tree like Structure in Json With Recursion

I'm struggling to get my head around this one, i've had a few attempts and failed miserably.
Basically I have a list of Employees in a database, each with an ID. A Employee can have a parent Employee (Refer as Manager).
I need to output the structure in some sort of tree in json format like shown in this URL
https://raw.githubusercontent.com/bumbeishvili/Assets/master/Projects/D3/Organization%20Chart/redesignedChartLongData.json
Here is a very basic structure example
The JSON can have a structure like this, containing an array of employees:
{
"employees":[
{
"id": 1764,
"name": "Maaz",
... //other fields... this employee has no parent field or
// "parent" : 0 (invalid value)
},
{
"id": 1765,
"parent": 1764,
//other fields... this employee has Maaz as parent
}
]
}
"parent" can simply be an optional field of the employee, containing theid of the parent employee.
If the json had a recursion (i.e. "parent": { /*...*/ }) this would create several issues such as:
Will the parent employee only be stored as second level, or also appear in the list as top level? This adds redundancy or alternatively, search complexity. because if 1764 only appears as child of 1765, you have to potentially recursively trasverse the whole list tree in order to find any employee.
What is the maximum depth of the recursion? With trasversal problems.
Inconsistency or circular relations, leading to loops. If A is parent of B and B is parent of A. Or if there is redundancy but upon deletion the employee does not get wiped anywhere.
More complex operations: if you have a chain of 5 parent-child employees and remove the top one, what do you do with the rest? You would have to define a policy. And adjust the tree everytime.
A flat list on the other hand required just 2 O(n) searches when you are looking for example, for employee 1765. You will then find its parent id and search the list again for an employee with than id, if it exists.
When you add an employee, add without a parent field and edit it later. When you delete an employee, just delete it and eventual broken links will be found at (flat) search time.

How to find last item in a repeated structure in bigquery

I have a nested repeated structure, the repeated structure is of variable length. For example, it could be a person object with a repeated structure that holds cities the person has lived in. I'd like to find the last item in that list say to find current city person lives in. Is there an easy way to do this, I tried looking around jsonpath functions but I'm not sure how to use it with "within". Any help please?
1) You can use LAST and WITHIN
SELECT
FIRST(cell.value) within record ,
LAST(cell.value) within record
FROM [publicdata:samples.trigrams]
where ngram = "! ! That"
2) or if you want something more advanced you can use POSITION
POSITION(field) - Returns the one-based, sequential position of field within a set of repeated fields.
You can check the samples from trigrams (click on Details to see the unflatten schema)
https://bigquery.cloud.google.com/table/publicdata:samples.trigrams?pli=1
And when you run POSITION, you get the ordering of that field.
SELECT
ngram,
cell.value,
position(cell.volume_count) as pos,
FROM [publicdata:samples.trigrams]
where ngram = "! ! That"
Now that you have the position, you can query for last one.

BO XI 3.1 List of values prompt item description return item key

I'm trying to define a LOV with Universe Designer that when used in a #Prompt shows the user the item description, but gives back the corresponding item key as result of user selection.
e.g. From a dimension table of countries with two columns as COUNTRY_ISO and COUNTRY_NAME, I would like to show COUNTRY_NAME values to user with #prompt, but get back the corresponding COUNTRY_ISO as return value of #prompt.
This is possible using Index Awareness. I'll describe the solution using the sample "Island Resorts Marketing" universe, but the concept should map to your specific need.
For this example, we'll create a prompt on the "Country" object in the "Resort" class. The prompt will display the country names, but the condition will apply to the country_id field.
First, we need to identify the keys. On the Keys tab of the Resort\Country object, add a new Primary Key using Resort_Country.country_id as the source:
(in your case, you'll do this on the COUNTRY_NAME object, using COUNTRY_ISO as the primary key)
Next, we create the predefined condition that will include the prompt. Create a new Predefined Condition, named "Select country", with the following definition:
Resort_Country.country_id = #Prompt('Choose a country','A','Resort\Country',Mono,primary_key)
What we're doing is is applying the condition to the ID field (resort_country.country_id), but using the country name (the Country object) as the source. Note the "primary_key" parameter -- this tells BO to use the PK from the referenced object.
Now to test. Create a WebI report and select the "Select country" filter along with a field to display. I chose Service Line:
I run the report and am presented with a list of country names. I choose France, and I get a list of the Service Lines associated with France. The SQL generated by this query, reflecting my prompt selection, is:
SELECT
Service_Line.service_line
FROM
Service_Line,
Country Resort_Country,
Resort
WHERE
( Resort_Country.country_id=Resort.country_id )
AND ( Resort.resort_id=Service_Line.resort_id )
AND ( Resort_Country.country_id = 2 )
Note the very last line, which shows that the condition is applied using the ID, even though I selected the country name "France".
References:
- XI3.1 Designer Guide #Prompt info, starting on page 520
- Dave's blog on Index Awareness
- Dave's blog on Index Awareness with prompts

MDS business rule

I am new with MDS, and I have a question about one to many relation mapping in MDS
I have a product, contains descriptions in multiple languages. I have created two entities with derived hierarchy structure: product (P_ID, P_name)and Addtional description(P_ID, P_Name_in_German, P_name_in_English).
Additonal description is a drop down from product table from MDS UI, but I only want to populate info that releated with its same P_ID. How can I achieve that? Can I use business rules here and how it should look like?
(2012 Master data service' web interface)
I have also faced a similar problem. I have decided to add multiple fields for languages and apply business rules for them. Let's see how it would work for your entity:
Product entity
{
Code
Name
Name_in_English (text)
Name_in_German (text)
Default_language (domain based, points to Languages entity)
}
Languages entity
{
Code
Name
}
Add values to the Languages entity:
Code = "EN", Mane = "EN"
Code = "DE", name = "DE"
Now we need to add the following business rules to the Product entity:
BR1:
{
IF Condition - Equals: Default_language equals "EN"
THEN Action - Change value: Name = Name_in_English
}
BR2:
{
IF Condition - Equals: Default_language equals "DE"
THEN Action - Change value: Name = Name_in_German
}
After that You will see the product names in your product entity only in proper language which is chosen by drop-down field Default_language.
The second option:
If You want user to see only the Name field and don't want him to see additional fields,
You can hide those fields (Name_in_English and Name_in_German) by setting their width to zero.
Moreover, You can use attribute groups to separate two modes of view:
first mode (for the regular user) - You see only Code and Name
second mode (for the administrator) - You see fields: Name_in_English, Name_in_German, Default_language.
For it to work You need to create two attribute groups:
1) attribute group "EN" (add attributes Name and Code to the group)
2) attribute group "DE" (add attributes Name_in_English, Name_in_German, Default_language to the group)
Hope something of that is helpful!
You're missing something. You said you have a derived hierarchy structure but you don't show a domain based attribute on the Additional description entity with a pointer back to the Product entity. Perhaps you were thinking that the P_ID for Additional Description is the pointer back but it isn't (based on your explanation). It is the entity Code identifier for the Additional Description entity and not the key you need that points back to Product. Perhaps you meant One to One. One to Many implies you have a separate Parent_P_ID back to the Product entity.
Add the Domain Based Parent_P_ID attribute to the Additional Description entity and then reconstruct your derived hierarchy structure. This may not be that helpful because I think you have left something out of the explanation of what you are trying to do.
Hi Cocunuts,
We can not assign derived hierarchy to entities in MDS 2012,but we can achieve this in MDS 2016 , Your Domain based attribute(Drop down) cannot be further filtered in MDS 2012.

DynamicQuery: How to select a column with linq query that takes parameters

We want to set up a directory of all the organizations working with us. They are incredibly diverse (government, embassy, private companies, and organizations depending on them ). So, I've resolved to create 2 tables. Table 1 will treat all the organizations equally, i.e. it'll collect all the basic information (name, address, phone number, etc.). Table 2 will establish the hierarchy among all the organizations. For instance, Program for illiterate adults depends on the National Institute for Social Security which depends on the Labor Ministry.
In the Hierarchy table, each column represents a level. So, for the example above, (i)Labor Ministry - Level1(column1), (ii)National Institute for Social Security - Level2(column2), (iii)Program for illiterate adults - Level3(column3).
To attach an organization to an hierarchy, the user needs to go level by level(i.e. column by column). So, there will be at least 3 situations:
If an adequate hierarchy exists for an organization(for instance, level1: US Embassy), that organization can be added (For instance, level2: USAID).--> US Embassy/USAID, and so on.
How about if one or more levels are missing? - then they need to be added
How about if the hierarchy need to be modified? -- not every thing need to be modified.
I do not have any choice but working by level (i.e. column by column). I does not make sense to have all the levels in one form as the user need to navigate hierarchies to find the right one to attach an organization.
Let's say, I have those queries in my repository (just that you get the idea).
Query1
var orgHierarchy = (from orgH in db.Hierarchy
select orgH.Level1).FirstOrDefault;
Query2
var orgHierarchy = (from orgH in db.Hierarchy
select orgH.Level2).FirstOrDefault;
Query3, Query4, etc.
The above queries are the same except for the property queried (level1, level2, level3, etc.)
Question: Is there a general way of writing the above queries in one? So that the user can track an hierarchy level by level to attach an organization.
In other words, not knowing in advance which column to query, I still need to be able to do so depending on some conditions. For instance, an organization X depends on Y. Knowing that Y is somewhere on the 3rd level, I'll go to the 4th level, linking X to Y.
I need to select (not manually) a column with only one query that takes parameters.
=======================
EDIT
As I just said to #Mark Byers, all I want is just to be able to query a column not knowing in advance which one. Check this out:
How about this
Public Hierarchy GetHierarchy(string name)
{
var myHierarchy = from hierarc in db.Hierarchy
where (hierarc.Level1 == name)
select hierarc;
retuen myHierarchy;
}
Above, the query depends on name which is a variable. It mighbe Planning Ministry, Embassy, Local Phone, etc.
Can I write the same query, but this time instead of looking to much a value in the DB, I impose my query to select a particular column.
var myVar = from orgH in db.Hierarchy
where (orgH.Level1 == "Government")
select orgH.where(level == myVariable);
return myVar;
I don't pretend that select orgH.where(level == myVariable) is even close to be valid. But that is what I want: to be able to select a column depending on a variable (i.e. the value is not known in advance like with name).
Thanks for helping
How about using DynamicQueryable?
http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
Your database is not normalized so you should start by changing the heirarchy table to, for example:
OrganizationId Parent
1 NULL
2 1
3 1
4 3
To query this you might need to use recursive queries. This is difficult (but not impossible) using LINQ, so you might instead prefer to create a parameterized stored procedure using a recursive CTE and put the query there.