2012-05-08 42 views
6

Tôi có một DB trong đó bảng article có mối quan hệ nhiều-nhiều với chính nó (thông qua article_rel) và articlestypes. Cha mẹ có một loại 1234, trong khi trẻ em có thể là một trong nhiều loại.Cách tốt hơn để truy vấn phụ

Tôi đang cố gắng tìm những bậc cha mẹ đó: hoặc không có con; hoặc, nếu họ có con, bài viết con gần đây nhất không phải là một tập hợp các loại nhất định.

Các công trình sau đây hợp lý cho phần thứ hai, nhưng không giải quyết phần đầu tiên. Mọi nỗ lực tôi đã thực hiện để rút truy vấn con để tôi có thể tham chiếu giá trị mà nó trả về (để thêm "hoặc là null") đã thất bại. Tôi cũng tự hỏi nói chung nếu có một cách tốt hơn để viết một cái gì đó như thế này.

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 

Trả lời

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 

Chỉ thử nghiệm trong tâm trí của tôi, không chắc chắn đó là 100% chính xác hay không. Bất kỳ sự điều chỉnh nào cũng được hoan nghênh. :)

0

Truy vấn đầu tiên Sẽ nhận các bậc cha mẹ không có con Trong khi Truy vấn thứ hai sẽ nhận được phụ huynh có bài viết con gần đây nhất không thuộc một nhóm các loại nhất định. UNION sẽ tự cung cấp cho bạn bộ kết quả DISTINCT.

Có rất nhiều lựa chọn lồng nhau nhưng đừng lo lắng tất cả chúng đang áp dụng bộ lọc trên tập kết quả chính đã tải của bạn để nó không ảnh hưởng đến hiệu suất, bạn có thể kiểm tra nó trong khi thực hiện truy vấn trên bàn điều khiển 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

Bạn sẽ có thể sử dụng MAX (được thêm) để chỉ tìm các trẻ em mới thêm. Bảng có nguồn gốc x tìm thấy ngày của đứa trẻ mới nhất được thêm vào cho n.id (xem this nếu phần đó không có ý nghĩa với bạn). Sau đó, t tìm thấy dữ liệu về đứa trẻ mới được thêm vào đó. Tôi đã sử dụng phép nối trái để có được con mới nhất của n.id bởi vì nếu không có con, thì nó sẽ để trống ở vị trí của đứa trẻ, cho bạn tất cả các bài viết không có con.

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 

Nếu có một cơ hội mà có nhiều hơn một bài viết với ngày chính xác thêm cùng, sau đó bạn phải sử dụng một bảng xuất phát cho t để kiểm tra tư cách bà con:

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 
Các vấn đề liên quan