<p>Let's say I have the following table:</p>

<pre><code>CustomerID ParentID Name
========== ======== ====
1          null     John
2          1        James
3          2        Jenna
4          3        Jennifer
5          3        Peter
6          5        Alice
7          5        Steve
8          1        Larry 
</code></pre>

<p>I want to retrieve in one query all the descendants of James (Jenna,Jennifer,Peter, Alice, Steve).
Thanks,
Pablo.</p>

You can't do recursion in SQL without stored procedures. The way to solve this is using Nested Sets, they basically model a tree in SQL as a set.
Notice that this will require a change to the current data model or possibly figuring out how to create a view on the original model.
Postgresql example (using very few postgresql extensions, just SERIAL and ON COMMIT DROP, most RDBMSes will have similar functionality):
Setup:
```
```
CREATE TABLE objects(
    id SERIAL PRIMARY KEY,
    name TEXT,
    lft INT,
    rgt INT
);

INSERT INTO objects(name, lft, rgt) VALUES('The root of the tree', 1, 2);
```
```
Adding a child:
```
```
START TRANSACTION;

-- postgresql doesn't support variables so we create a temporary table that 
-- gets deleted after the transaction has finished.

CREATE TEMP TABLE left_tmp(
    lft INT
) ON COMMIT DROP; -- not standard sql

-- store the left of the parent for later use
INSERT INTO left_tmp (lft) VALUES((SELECT lft FROM objects WHERE name = 'The parent of the newly inserted node'));

-- move all the children already in the set to the right
-- to make room for the new child
UPDATE objects SET rgt = rgt + 2 WHERE rgt > (SELECT lft FROM left_tmp LIMIT 1);
UPDATE objects SET lft = lft + 2 WHERE lft > (SELECT lft FROM left_tmp LIMIT 1);

-- insert the new child
INSERT INTO objects(name, lft, rgt) VALUES(
    'The name of the newly inserted node', 
    (SELECT lft + 1 FROM left_tmp LIMIT 1), 
    (SELECT lft + 2 FROM left_tmp LIMIT 1)
);

COMMIT;
```
```
Display a trail from bottom to top:
```
```
SELECT
    parent.id, parent.lft
FROM
    objects AS current_node
INNER JOIN
    objects AS parent
ON
    current_node.lft BETWEEN parent.lft AND parent.rgt
WHERE
    current_node.name = 'The name of the deepest child'
ORDER BY
    parent.lft;
```
```
Display the entire tree:
```
```
SELECT
    REPEAT('   ', CAST((COUNT(parent.id) - 1) AS INT)) || '- ' || current_node.name AS indented_name
FROM
    objects current_node
INNER JOIN
    objects parent
ON
    current_node.lft BETWEEN parent.lft AND parent.rgt
GROUP BY
    current_node.name,
    current_node.lft
ORDER BY
    current_node.lft;
```
```
Select everything down from a certain element of the tree:
```
```
SELECT
    current_node.name AS node_name
FROM
    objects current_node
INNER JOIN
    objects parent
ON
    current_node.lft BETWEEN parent.lft AND parent.rgt
AND
    parent.name = 'child'
GROUP BY
    current_node.name,
    current_node.lft
ORDER BY
    current_node.lft;
```
```