2012-05-08 66 views
6

我有一個DB,其中article表與自己有多對多的關係(通過article_rel)和articlestypes。父母有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 

回答

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 

只測試在我的腦海裏,不知道它是100%正確。任何更正都非常受歡迎。 :)

0

第一個查詢將獲得父母誰沒有孩子雖然第二個查詢將獲得其最新的子文章不是一定類型的父母。 UNION將自己爲您提供DISTINCT結果集。

有這麼多的嵌套選擇,但不用擔心它們都在你已經加載的主結果集上應用過濾器,所以它不會影響性能,你可以在Db控制檯上執行查詢時測試它。

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) 
1

您應該可以使用MAX(增加)來查找最新添加的孩子。派生表x爲父項n.id查找最新添加的子項的日期(如果該部分對您沒有意義,請參閱this)。然後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 
相關問題