开发者

How can I turn a single row column into a scalar in SQL?

This is sort of what I want to do, but MySQL doesn't seem to accept it.

SELECT Name, Content, Lft, Rht FROM Articles WHERE
    (Lft > (SELECT Lft FROM Articles WHERE idArticle = 1))
    AND WHERE
    (Rht < (SELECT Rht FROM Articles WHERE idArticle = 1));

I'm implementing the modified preorder tree transversal algorithm, and I want to get all the children of an Article using a single database query.

The Articles table looks like this:

Articles
+=============+===========+
| Type        | Name      |
+=============+===========+
| VARCHAR(45) | Name      |
+-------------+--开发者_运维百科---------+
| LONGTEXT    | Content   |
+-------------+-----------+
| INT         | Lft       |
+-------------+-----------+
| INT         | Rht       |
+-------------+-----------+
| INT         | idArticle |
+-------------+-----------+

idArticle is a primary key, and there are UNIQUE indexes on the Lft and Rht columns.

How might something like this be accomplished?

*Note: I'm currently using MySQL but I'd like to avoid any MySQL extensions where possible, because there are possible plans to move to another DB like Postgres or Oracle sometime in the future...


It's not being accepted because the WHERE keyword can only appear once in a query (outside of a subquery):

SELECT x.name,  
       x.content, 
       x.lft, 
       x.rht 
  FROM ARTICLES x
 WHERE EXISTS(SELECT NULL
                FROM ARTICLES y
               WHERE y.idarticle = 1
                 AND y.lft < x.lft)
  AND EXISTS(SELECT NULL
               FROM ARTICLES z
              WHERE z.idarticle = 1
                AND z.rht > x.rht)


Apparently it was just a simple syntax error (too many WHERE), but if you want to avoid the scalar subselect, you could also do a join (with the potential advantage that the row with idArticle 1 only needs to be loaded once, an optimization that your query planner may or may not be able to figure out by itself):

SELECT a.Name, a.Content, a.Lft, a.Rht FROM Articles a
   join Articles b on (b.idArticle =1 )
   where a.lft > b.lft and a.rht < b.rht;

Alternate equivalent

SELECT a.Name, a.Content, a.Lft, a.Rht 
  FROM Articles a
  join Articles b on a.lft > b.lft 
                 and a.rht < b.rht 
                 AND b.idArticle = 1 ;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜