6

我有一个数据库,其中article表与自身具有多对多关系(通过article_rel)并articles具有types. 父母有一个类型 1234,而孩子可以是几种类型之一。

我正在努力寻找以下父母: 没有孩子;或者,如果他们有孩子,则最近的子文章不是特定类型的集合。

以下内容适用于第二部分,但不涉及第一部分。我为拉出子查询以引用它返回的值(添加“或为空”)所做的每一次尝试都失败了。我也想知道是否有更好的方法来写这样的东西。

SELECT 
 CONCAT('http://www.sitename.com/', n.id, '.html') as URL,
 n.added,
 u.email,
 n.body
 #c.body
 FROM
     warehouse.article n 
 inner join site.user u on n.user_id = u.id
 inner join warehouse.article_param np on np.id = n.id and np.param_name = 'ready' and np.param_value = 'true'
 where
     n.type_id = 1234 
 and
     (select 
           c.type_id 
      from 
           warehouse.article c, 
           warehouse.article_rel r
      where
           r.child_nid = c.id
           and r.parent_nid = n.id
      order by 
           c.added desc 
      limit 1)
      not in (2245,5443)
 order by 
      n.updated desc
4

3 回答 3

1

您应该能够使用 MAX(add) 仅查找最新添加的子项。派生表 x 查找父 n.id 的最新添加的孩子的日期(如果该部分对您没有意义,请参阅此)。然后 t 找到关于最新添加的孩子的数据。我使用左连接来获取 n.id 的最新添加的孩子,因为如果没有孩子,那么它将在孩子的位置留下空值,从而为您提供所有没有孩子的文章。

SELECT n.added, CONCAT('http://www.sitename.com/', n.id, '.html') as URL,
u.email, n.body #c.body
FROM warehouse.article n 
inner join site.user u on n.user_id = u.id
inner join warehouse.article_param np on np.id = n.id and np.param_name = 'ready' and np.param_value = 'true'
left join (SELECT r.parent_nid, MAX(added) as latest
              FROM warehouse.article c
              INNER JOIN warehouse.article_rel r on c.id = r.child_nid
              GROUP BY r.parent_nid) as x on x.parent_nid = n.id
left join warehouse.article t on t.added = x.latest
where n.type_id = 1234 and (t.type_id is null or t.type_id not in (2245,5443))
order by n.updated desc

如果有可能有不止一篇文章具有完全相同的添加日期,那么您必须使用 t 的派生表来检查亲子关系:

left join (SELECT c.type_id, c.id, c.added, r.parent_nid
           FROM warehouse.article c
           INNER JOIN warehouse.article_rel r on c.id = r.child_nid)
           as t on t.parent_nid = n.id and t.added = x.latest
于 2012-05-21T18:11:05.073 回答
0
SELECT 
n.added,
CONCAT('http://www.sitename.com/', n.id, '.html') as URL,
u.email,
n.body
#c.body
FROM
    warehouse.article n 
inner join site.user u on n.user_id = u.id
inner join warehouse.article_param np on np.id = n.id and np.param_name = 'ready' and np.param_value = 'true'
left join 
     (
           select r.parent_nid, c.type_id 
           from warehouse.article c
           left join warehouse.article_rel r on r.child_nid = c.id and r.parent_nid = n.id     
           order by c.added desc 
           limit 1
      ) child_type
      on child_parent_nid = n.id
where
    n.type_id = 1234 and (child_type.type_id not in (2245,5443) or child_type.type_id is null)
order by 
    n.updated desc

Only test in my mind, not sure it's 100% correct or not. Any correction is very welcome. :)

于 2012-05-08T07:30:04.630 回答
0

First Query Will Get the parents who have no children While Second Query will get the parent whose most recent child article is not of a certain set of types. UNION will itself provide you the DISTINCT result set.

There are so many nested select but don't worry all of them are applying filters on your already loaded main result set so it will not effect performance, you can test it while executing query on Db console.

SELECT
 CONCAT('http://www.sitename.com/', n.id, '.html') AS URL,
 n.added,
 u.email,
 n.body
 FROM
 warehouse.article n
 JOIN site.user u ON n.user_id = u.id
 JOIN warehouse.article_param np ON np.id = n.id AND np.param_name = 'ready' AND <br/> np.param_value = 'true'
 LEFT JOIN warehouse.article_rel r ON r.parent_nid = n.id
 WHERE
 n.type_id = 1234  AND r.id IS NULL

 UNION

 SELECT URL,added,email,body FROM
 (SELECT * FROM
(SELECT

 CONCAT('http://www.sitename.com/', n.id, '.html') AS URL,
 n.added,
 u.email,
 n.body,
 nr.type_id
 FROM
 warehouse.article n
 JOIN site.user u ON n.user_id = u.id
 JOIN warehouse.article_param np ON np.id = n.id AND np.param_name = 'ready' AND <br/> np.param_value = 'true'
 JOIN warehouse.article_rel r ON r.parent_nid = n.id
 JOIN warehouse.article nr ON r.child_nid=nr.id
 WHERE
 n.type_id = 1234
 ORDER BY n.id DESC
 ) AS tbl1
GROUP BY id
Where  type_id NOT IN (2245,5443)
于 2012-05-08T07:46:54.390 回答