Author Topic: Get all elements of hierarchy  (Read 5479 times)

martin1

  • EA User
  • **
  • Posts: 57
  • Karma: +0/-0
    • View Profile
Get all elements of hierarchy
« on: August 05, 2024, 10:46:05 pm »
Dear all, I try to accomplish the following:
* I want to write an SQL query returning all elements (e.g. requirements, classes, blocks) of a package hierarchy
* The only parameter is the Package_ID of the "root" node
* No recursion mechanisms, no macros
* The number of levels to go down the hierarchy can be fixed and set to e.g. 3

My current idea was to use t_object and join t_package multiple times and get the elements. But it doesn't work yet.

Code: [Select]
SELECT *
FROM ((((t_object AS o
INNER JOIN t_package AS p0 ON o.Package_ID = p0.Package_ID)
LEFT JOIN t_package AS p1 ON p1.Parent_ID = p0.Package_ID)
LEFT JOIN t_package AS p2 ON p2.Parent_ID = p1.Package_ID)
LEFT JOIN t_package AS p3 ON p3.Parent_ID = p2.Package_ID)
WHERE p0.Package_ID = <number>

Any ideas what's missing and how to realize this?


Geert Bellekens

  • EA Guru
  • *****
  • Posts: 13232
  • Karma: +551/-33
  • Make EA work for YOU!
    • View Profile
    • Enterprise Architect Consultant and Value Added Reseller
Re: Get all elements of hierarchy
« Reply #1 on: August 05, 2024, 11:23:07 pm »
Code: [Select]
p0 ON o.Package_ID = p0.Package_IDMeans you only want elements that are directly under p0.

What you need is to end with t_object o and join that with any of the package ID's.

Code: [Select]
inner join t_object o on o.package_ID in (p0.package_ID, p1.package_ID, p2.package_ID, p3.Package_ID)
Geert

martin1

  • EA User
  • **
  • Posts: 57
  • Karma: +0/-0
    • View Profile
Re: Get all elements of hierarchy
« Reply #2 on: August 05, 2024, 11:41:40 pm »
So in total, this would read:
Code: [Select]
SELECT *
FROM ((((t_object AS p0
LEFT JOIN t_package AS p1 ON p1.Parent_ID = p0.Package_ID)
LEFT JOIN t_package AS p2 ON p2.Parent_ID = p1.Package_ID)
LEFT JOIN t_package AS p3 ON p3.Parent_ID = p2.Package_ID)
INNER JOIN t_object AS o on o.Package_ID in (p0.Package_ID, p1.Package_ID, p2.Package_ID, p3.Package_ID))
WHERE p0.Package_ID = <number>

I get a syntax error on that one? I am not so sure if IN can be used within JOIN?
« Last Edit: August 05, 2024, 11:49:07 pm by martin1 »

Geert Bellekens

  • EA Guru
  • *****
  • Posts: 13232
  • Karma: +551/-33
  • Make EA work for YOU!
    • View Profile
    • Enterprise Architect Consultant and Value Added Reseller
Re: Get all elements of hierarchy
« Reply #3 on: August 06, 2024, 12:02:46 am »
t_object AS p0 should be t_package as p0 I guess.

And you shouldn't use the "AS" keyword for table aliasses.

You can definitely use IN in a join. I'm not sure which database you are working with, but if the IN doesn't work, you can replace that with OR's.

Geert

Richard Freggi

  • EA User
  • **
  • Posts: 486
  • Karma: +18/-7
    • View Profile
Re: Get all elements of hierarchy
« Reply #4 on: August 06, 2024, 01:28:16 am »
What's wrong with recursive, I find it easier and safer.
You can get all package GUIDs then from there get all elements within that package

Code: [Select]
WITH RECURSIVE pkgbranch (eaguid, pkgid, pkgname, parentid, lvl) AS
(SELECT p.ea_guid, Package_ID, p.Name, p.Parent_ID, 1
FROM t_package p
WHERE p.ea_guid = '{xxxx}'
UNION ALL
SELECT p.ea_guid, p.Package_ID, p.Name, p.Parent_ID, pb.lvl+1
FROM t_package p
JOIN pkgbranch pb ON pb.pkgid = p.Parent_ID)

SELECT * FROM pkgbranch;

Geert Bellekens

  • EA Guru
  • *****
  • Posts: 13232
  • Karma: +551/-33
  • Make EA work for YOU!
    • View Profile
    • Enterprise Architect Consultant and Value Added Reseller
Re: Get all elements of hierarchy
« Reply #5 on: August 06, 2024, 01:51:52 am »
What's wrong with recursive, I find it easier and safer.
You can get all package GUIDs then from there get all elements within that package

Code: [Select]
WITH RECURSIVE pkgbranch (eaguid, pkgid, pkgname, parentid, lvl) AS
(SELECT p.ea_guid, Package_ID, p.Name, p.Parent_ID, 1
FROM t_package p
WHERE p.ea_guid = '{xxxx}'
UNION ALL
SELECT p.ea_guid, p.Package_ID, p.Name, p.Parent_ID, pb.lvl+1
FROM t_package p
JOIN pkgbranch pb ON pb.pkgid = p.Parent_ID)

SELECT * FROM pkgbranch;
You can't use recursive queries in EA searches, or Repository.SQLQuery
They need the query to start with Select

Geert

martin1

  • EA User
  • **
  • Posts: 57
  • Karma: +0/-0
    • View Profile
Re: Get all elements of hierarchy
« Reply #6 on: August 06, 2024, 03:40:52 am »
t_object AS p0 should be t_package as p0 I guess.
Of course you're right.

You can definitely use IN in a join. I'm not sure which database you are working with, but if the IN doesn't work, you can replace that with OR's.
What is the goal of your last INNER JOIN, is the IN statement a shortcut to perform a JOIN 4x? Or JOIN once, and filter results?

Btw, INNER JOIN doesn't seem to work here ("expression not supported"). LEFT JOIN seems to bypass this.
« Last Edit: August 06, 2024, 04:14:35 am by martin1 »

martin1

  • EA User
  • **
  • Posts: 57
  • Karma: +0/-0
    • View Profile
Re: Get all elements of hierarchy
« Reply #7 on: August 06, 2024, 04:35:49 am »
You can definitely use IN in a join. I'm not sure which database you are working with, but if the IN doesn't work, you can replace that with OR's.

When I replace X with 0,1,2,3 it seems to work for each individual level. Any ideas how to achieve this in one query?

Code: [Select]
SELECT *
FROM ((((t_package p0
LEFT JOIN t_package p1 ON p1.Parent_ID = p0.Package_ID)
LEFT JOIN t_package p2 ON p2.Parent_ID = p1.Package_ID)
LEFT JOIN t_package p3 ON p3.Parent_ID = p2.Package_ID)
LEFT JOIN t_object o ON o.Package_ID = pX.Package_ID)
WHERE p0.Package_ID = <number>

Edit: 4x UNION seems to do the trick, but I think this is the least elegant solution.
« Last Edit: August 06, 2024, 05:22:17 am by martin1 »

Geert Bellekens

  • EA Guru
  • *****
  • Posts: 13232
  • Karma: +551/-33
  • Make EA work for YOU!
    • View Profile
    • Enterprise Architect Consultant and Value Added Reseller
Re: Get all elements of hierarchy
« Reply #8 on: August 06, 2024, 07:34:59 am »
LEFT JOIN t_object o ON (o.Package_ID = p0.Package_ID or o.package_ID = p1.Package_ID or...)

Geert

martin1

  • EA User
  • **
  • Posts: 57
  • Karma: +0/-0
    • View Profile
Re: Get all elements of hierarchy
« Reply #9 on: August 06, 2024, 03:41:46 pm »
LEFT JOIN t_object o ON (o.Package_ID = p0.Package_ID or o.package_ID = p1.Package_ID or...)
I already tried that, this gives me a syntax error in EA14.

Thanks for your support!

BobM

  • EA User
  • **
  • Posts: 143
  • Karma: +9/-0
    • View Profile
Re: Get all elements of hierarchy
« Reply #10 on: August 06, 2024, 09:34:35 pm »
Code: [Select]
SELECT
CLASSGUID = o.ea_guid
,CLASSTYPE = o.object_type
    , o.*
FROM ((((t_package AS p0
LEFT JOIN t_package AS p1 ON p1.Parent_ID = p0.Package_ID)
LEFT JOIN t_package AS p2 ON p2.Parent_ID = p1.Package_ID)
LEFT JOIN t_package AS p3 ON p3.Parent_ID = p2.Package_ID)
INNER JOIN t_object AS o on o.Package_ID in (p0.Package_ID, p1.Package_ID, p2.Package_ID, p3.Package_ID))
WHERE 1=1
AND p0.Package_ID = <number>

martin1

  • EA User
  • **
  • Posts: 57
  • Karma: +0/-0
    • View Profile
Re: Get all elements of hierarchy
« Reply #11 on: August 06, 2024, 09:42:04 pm »
Code: [Select]
SELECT
CLASSGUID = o.ea_guid
,CLASSTYPE = o.object_type
    , o.*
FROM ((((t_package AS p0
LEFT JOIN t_package AS p1 ON p1.Parent_ID = p0.Package_ID)
LEFT JOIN t_package AS p2 ON p2.Parent_ID = p1.Package_ID)
LEFT JOIN t_package AS p3 ON p3.Parent_ID = p2.Package_ID)
INNER JOIN t_object AS o on o.Package_ID in (p0.Package_ID, p1.Package_ID, p2.Package_ID, p3.Package_ID))
WHERE 1=1
AND p0.Package_ID = <number>

Thanks. In EA14 this does not work, EA reports a redundant bracket "(".

BobM

  • EA User
  • **
  • Posts: 143
  • Karma: +9/-0
    • View Profile
Re: Get all elements of hierarchy
« Reply #12 on: August 06, 2024, 09:51:01 pm »
a bit more simplified in brackets (is always the same result)

I would genuinely be surprised if they ever did updates on the SQL editor (I would be happy, but it's definitely not on the priority list of sparx devs)

Code: [Select]
SELECT
CLASSGUID = o.ea_guid
,CLASSTYPE = o.object_type
    , o.*
FROM t_package AS p0
LEFT JOIN t_package AS p1 ON p1.Parent_ID = p0.Package_ID
LEFT JOIN t_package AS p2 ON p2.Parent_ID = p1.Package_ID
LEFT JOIN t_package AS p3 ON p3.Parent_ID = p2.Package_ID
INNER JOIN t_object AS o on o.Package_ID in (p0.Package_ID, p1.Package_ID, p2.Package_ID, p3.Package_ID)
WHERE 1=1
AND p0.Package_ID = <number>
« Last Edit: August 06, 2024, 09:52:58 pm by BobM »

martin1

  • EA User
  • **
  • Posts: 57
  • Karma: +0/-0
    • View Profile
Re: Get all elements of hierarchy
« Reply #13 on: August 06, 2024, 10:49:26 pm »
In this old version you have to use brackets for multiple JOINs, to avoid confusion of the SQL engine.

BobM

  • EA User
  • **
  • Posts: 143
  • Karma: +9/-0
    • View Profile
Re: Get all elements of hierarchy
« Reply #14 on: August 06, 2024, 11:22:01 pm »
I never realized the SQL engine used to be worse as the one we currently have to use.