所以我试图编写一个MySQL查询来用三个单独的查询替换当前在PHP中完成的操作。我有一个只有两个值的类别表:ID和名称。还有另外两个表,每个表都有一个外键,引用第一个表中的ID。我需要从Categories表中获取所有值的列表,以及在其他两个表中每个值引用的值的计数。我可以使用单独的查询从每个第二个表中准确地获取计数:
SELECT nga_calevir_event_categories.*, COUNT(nga_calevir_events.event_id) AS event_total
FROM nga_calevir_event_categories
LEFT JOIN (nga_calevir_events)
ON nga_calevir_event_categories.id = nga_calevir_events.event_category
GROUP BY nga_calevir_event_categories.id;
和
SELECT nga_calevir_event_categories.*, COUNT(nga_usermeta.user_id) AS member_total
FROM nga_calevir_event_categories
LEFT JOIN (nga_usermeta)
ON (nga_usermeta.meta_value = nga_calevir_event_categories.id
AND nga_usermeta.meta_key = 'category_id')
GROUP BY nga_calevir_event_categories.id;
但是,当我尝试组合这些查询时,它会开始为这两个计数提供不正确的结果。以下是合并查询:
SELECT nga_calevir_event_categories.*,
COUNT(nga_calevir_events.event_id) AS event_total,
COUNT(nga_usermeta.user_id) AS member_total
FROM nga_calevir_event_categories
LEFT JOIN (nga_calevir_events)
ON nga_calevir_event_categories.id = nga_calevir_events.event_category
LEFT JOIN (nga_usermeta)
ON (nga_usermeta.meta_value = nga_calevir_event_categories.id
AND nga_usermeta.meta_key = 'category_id')
GROUP BY nga_calevir_event_categories.id;
似乎第一排的数量增加了一倍。我现在已经尝试了几个小时了,我无法理解。有任何想法吗?如果您需要更多信息来帮助我,请与我们联系。
答案 0 :(得分:0)
这不起作用,因为连接是组合的:
SELECT nga_calevir_event_categories.*,
COUNT(nga_calevir_events.event_id) AS event_total,
COUNT(nga_usermeta.user_id) AS member_total
FROM nga_calevir_event_categories
LEFT JOIN (nga_calevir_events)
ON nga_calevir_event_categories.id = nga_calevir_events.event_category
-- The above is almost the same as an inner join, so long as every
-- category has at least one event.
LEFT JOIN (nga_usermeta)
ON (nga_usermeta.meta_value = nga_calevir_event_categories.id
AND nga_usermeta.meta_key = 'category_id')
-- This is where you're going to get weird. This is going to join
-- every row already figured out- basically, a row for every event
-- with every usermeta that matches!
GROUP BY nga_calevir_event_categories.id;
这实际上是两个查询 - 将usermeta加入类别没有明智的方法(除非我误解了应用程序)。但是,有一种方法可以将它放入一个SQL语句中。试试这个:
SELECT categories.*,
coalesce(event_hits.hits, 0) + coalesce(meta_hits.hits, 0) as total_hits
FROM nga_calevir_event_categories as categories
LEFT JOIN
(select event_category as catid, count(*) as hits
FROM (nga_calevir_events)
group by event_category
) as event_hits ON event_hits.catid = categories.id
LEFT JOIN (
select meta_value as catid, count(*) as hits
FROM nga_usermeta
WHERE meta_key = 'category_id'
group by meta_value
) as meta_hits ON meta_hits.catid = categories.id
这使用两个内部选择来获取用于两个表中每个表的类别ID的计数,然后将这些内部选择连接到实际类别,并将它们各自返回的计数相加。我们使用COALESCE来确保其中一个表中没有使用的地方,假定为0。
希望这有帮助!