I want to retrieve the path to a single node in a hierachical database where only the parent node ID is stored as a reference. Could someone give me a query or some advice on how to write a query (ideally the first option - I'm a MySQL noob) so that all the node titles in the end node's path are given in a generated table?
id name depth
10 Top level 0
22 Second level 1
34 3rd level 2
43 End node 3
I want to use this data to create on of those "you are here" lists like:
Home > Forums > Stuffs > ... > Topics
Thanks for any help,
James
This is only possible for a fixed number of levels, as there is no recursion in SQL.
You can convert your data structure from the "adjacency list" model you have to the so-called "nested sets" model. With that model a "find the path to the top" query is possible.
Related
Does anyone have an easy way to convert nested JSON to a flat SQL table? Just want to repeat the higher level data on each of the lower level detail. It looks like it can be done in mapping, I have tried as per the MS documentation but got a table full of NULL. Here is what I have tried and the result.
json
Option 1
Result: Only returns the first record of the ‘assignedLicences’
Option1
Option 2:
Returns multiple ‘assignedLicenses’ for each user, but only returns the first user id in each page.
Option2
Option3: as per the MS documentation
Result: returns all NULL values
Option3
You can have a try:
1.click import schemas button
2.if you have a JsonArray,select it.
3.you can directly see and edit the fields' JSON paths by opening Advanced editor .
Here is a Microsoft documentation about it.Please refer to this.
Hope this can help you.
i got this table structure :
-----------------------------------
Name DocID ParentID
-----------------------------------
doc1 1 NULL
doc2 2 1
doc3 3 NULL
doc4 4 3
doc5 5 1
The query should output the tree structure with parents and childs nodes, the level can have any value.
The output is like that :
doc1
| --doc2
| --doc5
|
doc3
--doc4
Can you help to do that in mysql in a simple or recursive query in mysql ?
Writing a query like that for your data model (known as an Adjacency List) would be relatively complex and inefficient. If you really need to do so, check out http://www.artfulsoftware.com/mysqlbook/sampler/mysqled1ch20.html#adjacency_list_model.
If you don't mind altering your data model, there are two approaches:
Nested Sets - http://en.wikipedia.org/wiki/Nested_set_model. This is the most common and easy to use. There are plenty of scripts and frameworks that facilitate the use of nested sets without requiring you to manage all of the low level operations. If you have existing data, you can loop through the existing rows and insert them into the new nested set table, and you'll be good to go.
Alternatively, you could store the complete hierarchical path of each document (like breadcrumbs) in a new column. Something like:
------
Path
------
doc1
doc1>doc2
doc1>doc5
doc3
doc3>doc4
The second method would allow you to do a simple SELECT with an ORDER BY on "Path". You could then look at the number of ">" (or whatever character(s) you use) to determine the document's level in the hierarchy (how much to indent it in the UI).
The second method is not ideal because it requires more maintenance. If you change one parent-child relationship, you end up having to regenerate all of the paths. Nested Sets also involve a fair amount of row updates, but it's done very efficiently.
I've got records in my MySQL projects database that have several boolean flags to help me sort the data. I have 3 categories planning, landscape, and environmental and 4 classes (or subcategories) for each category; industrial, government, education, residential.
My goal is to use ColdFusion to create and store the project_id numbers in an array of some kind that will basically have the projects sorted by category and class. That way I can grab just the industrial projects in the planning category and construct a link to that project.
So, the first position in the array would be planning and inside that first position would be the 4 classes, then, within that would be all of the project_id numbers that returned true for those particular criteria.
The logic I'm looking to create goes like this...
Loop over the query result, if planning = true and industrial = true, place the project id # into the planning array inside the industrial array.
How can I use <cfloop> to loop over the list of project records, recognize the category and class flags and construct a clean and usable dataset? Can this be handles in the query in some way?
Figure out the desired data structure
look at your existing data structure
figure out the algorithm to translate from one to the other
You may cfloop the query, and use a large cfswitch (or large set of if-then-else) to figure out how you want to store the id in your desired data structure. Or if you can map the class/category name as a struct key, then it might be easier.
Or you may use cfoutput group="" if it helps (cfloop group="" is available on in CF10+)
Finally, maybe you don't even need the data structure, just use Query of Queries wherever you need.
You may be able to utilize the Underscore.cfc library for this. For example, you could use the filter function to extract an array of structs representing the query rows you want:
planningArray = _.filter(queryResult, function(row){
return (row.planning == true && row.industrial == true);
});
I have the following table, MenuItems, in the database:
ID ParentID Name
--- --------- -----
1 0 Item 1
2 1 Item 2
3 1 Item 3
4 0 Item 4
5 3 Item 5
I want to write an extension method to get all menu items to the root of the tree. Something like this:
public IQueryable<MenuItem> GetToRoot(this IQueryable<MenuItem> source, int menuItemID)
{
return from m in source
????
????
select m;
}
If I call this extension method with the data above for the menu item with ID 3, I should get:
ID ParentID Name
--- --------- -----
1 0 Item 1
3 1 Item 3
Is this possible with Linq2Sql with only one call to the database?
I don't think you'll be able to do it in a single query, and here's my thinking: discovering an item's parent effectively requires one join of the table with itself. Each additional menu level requires one more join of the table with itself. How many joins/additional levels will you need to reach the root? You won't know until you perform each one, right? So, whether on the database/SQL side or in LINQ to SQL, you'll have to take each step one at a time.
If you know your menu system won't go beyond a certain depth, I suppose you could set up a LINQ to SQL query that joins the table with itself that number of times, but that sounds ugly.
What I would suggest is setting up an association of the table with itself in your DBML designer, that would give you a parent EntityRef<> property on the class. Since cycles are not allowed in your LoadOptions (and therefore the parent cannot be pre-loaded), you could force the lazy load of the parent in the entity's partial OnLoaded() method.
Here are some relevant SO questions:
https://stackoverflow.com/questions/1435229/hierarchy-problem-replace-recursion-with-linq-join
LINQ to SQL for self-referencing tables?
Here is a server-side/SQL treatment of the problem:
http://www.sqlteam.com/article/more-trees-hierarchies-in-sql
Here is someone who has written some helper code:
http://www.scip.be/index.php?Page=ArticlesNET18
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.