1

I'm using MySQL (5.7.20) to store a folder hierarchy. Each folder is stored together with all direct and indirect parents including the distance. As an example, the following folders

A
+- B
   + C
   + D

would be stored like this:

parent | child | dist
-------+-------+-----
A      | A     | 0
A      | B     | 1
A      | C     | 2
A      | D     | 2
B      | B     | 0
B      | C     | 1
B      | D     | 1
C      | C     | 0
D      | D     | 0

Additionally, there is another table that links a folder to one or many users, like this:

child | user
------+-----
A     | U1
B     | U1
C     | U2
D     | U2

What I'm now trying to achieve is to query this hierarchy by user in a way that only the highest matches in the hierarchy are returned.

So as in the example above, if I query for folders of user U1, I only want A as a result, because the second match B is a child of A. On the other hand, if I query for folders of user U2, the result should be C, D as both folders are on the same hierarchy level.

The closest query I could imagine was SELECT child, dist AS d FROM folders JOIN users ON folders.child = users.child GROUP BY folders.parent HAVING d = min(d); but unfortunately it is not giving the right results, as for example a query for user U1 would still give folders A,B as a result.

Does anyone have an idea how this could be done?

2
  • What if A had another child (E), related to U2? Would asking for U1 return C, D and E? Commented Mar 2, 2018 at 14:29
  • Exactly, this should result in C,D,E for user U2 as none of the folders would be parent (or child) of another one
    – Jan Gassen
    Commented Mar 2, 2018 at 14:30

1 Answer 1

2

I think you want this. All the results from users table except those that have a parent in users:

SELECT u.user, u.child
FROM users AS u 
WHERE NOT EXISTS
      ( SELECT 1 
        FROM users AS u2
             JOIN folder AS f 
             ON f.parent = u2.child
        WHERE f.child = u.child
          AND f.dist > 0         -- this could be: AND f.parent <> f.child
          AND u2.user = u.user
      ) ; 
8
  • Thanks, this works well! The only problem left is that I also need other columns from the folders table as well. But I guess I could just join the result with the folders table again.
    – Jan Gassen
    Commented Mar 2, 2018 at 14:59
  • What other columns are there in folders? Commented Mar 2, 2018 at 15:00
  • The parent column for example should be part of the result
    – Jan Gassen
    Commented Mar 2, 2018 at 15:02
  • So, for the U2 case (with C,D,E output), what would the parents be? All parents of C,D and E? Commented Mar 2, 2018 at 15:03
  • like [(C,B), (D,B), (E, A)], the first value being the folder/child and the second value the parent
    – Jan Gassen
    Commented Mar 2, 2018 at 15:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.