我有一个数据库,其中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
答案 0 :(得分:1)
您应该能够使用MAX(已添加)来查找最新添加的孩子。派生表x查找父n.id的最新添加子日期(如果该部分对您没有意义,请参阅this)。然后找到有关最新添加的孩子的数据。我使用左连接来获取n.id的最新添加的子项,因为如果没有子项,那么它将在子项的位置留下null,为您提供所有没有子项的文章。
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
如果有多篇文章可能具有完全相同的添加日期,那么您必须使用派生表来检查父项:
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
答案 1 :(得分: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%正确。任何更正都非常受欢迎。 :)
答案 2 :(得分: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)