我有以下查询:
SELECT *
FROM (
SELECT
m.id AS id,
reference_id,
title,
created_by,
publish_up,
state
FROM z_news_master m
LEFT JOIN z_news_english c ON m.id = c.reference_id
WHERE c.created_by = 17152
ORDER by c.id DESC
) AS A
UNION
SELECT * FROM (
SELECT
m.id AS id,
reference_id,
title,
created_by,
publish_up,
state
FROM z_news_master m
LEFT JOIN z_news_spanish c ON m.id = c.reference_id
WHERE c.created_by = 17152
ORDER by c.id DESC
) AS B
GROUP BY id
基本上,我有3个表(z_news_master, z_news_english, z_news_spanish
),用西班牙语或英语存储新闻。 z_news_master
表包含通用新闻信息,z_news_english
和z_news_spanish
包含各自语言的新闻。
我需要获取新闻列表,如果新闻在两个语言表中,它应该只返回一个(不重复),上面的代码可以完成工作,但如果有新的英语和西班牙语,记录重复。
我也想知道为什么GROUP BY id
和GROUP BY reference_id
不起作用?
答案 0 :(得分:1)
如果存在首选语言的相应行,请使用NOT EXISTS子查询删除后备语言行。假设首选语言为“english”,则查询为:
SELECT
m.id AS id,
reference_id,
title,
created_by,
publish_up,
state
FROM z_news_master m
JOIN z_news_english c ON m.id = c.reference_id
WHERE c.created_by = 17152
UNION ALL
SELECT
m.id AS id,
reference_id,
title,
created_by,
publish_up,
state
FROM z_news_master m
JOIN z_news_spanish c ON m.id = c.reference_id
WHERE c.created_by = 17152
AND NOT EXISTS (
SELECT *
FROM z_news_english e
WHERE e.reference_id = m.id
AND e.created_by = c.created_by
)
ORDER by id DESC
请注意,不需要GROUP BY。 LEFT JOIN没有意义,因为右表中的列有一个WHERE条件(将LEFT JOIN转换为INNER JOIN)。
答案 1 :(得分:0)
您可以在不使用联合的情况下执行此操作。下面的语句从主表中获取所有行,并连接西班牙语和英语表中的所有现有行。 如果西班牙语表中存在行,则它使用该表中的值。如果英语表中存在行,而不是西班牙语表,则它使用该表中的值。 如果英语或西班牙语表中不存在匹配的行,则返回主表中的列。
您可以通过更改WHEN的顺序来更改优先级。
SELECT
CASE
WHEN NOT s.id IS NULL THEN s.id
WHEN NOT e.id IS NULL THEN e.id
ELSE m.id AS `id`,
CASE
WHEN NOT s.reference_id IS NULL THEN s.reference_id
WHEN NOT e.reference_id IS NULL THEN e.reference_id
ELSE m.reference_id AS `reference_id`,
CASE
WHEN NOT s.title IS NULL THEN s.title
WHEN NOT e.title IS NULL THEN e.title
ELSE m.title AS `title`,
CASE
WHEN NOT s.created_by IS NULL THEN s.created_by
WHEN NOT e.created_by IS NULL THEN e.created_by
ELSE m.created_by AS `created_by`,
CASE
WHEN NOT s.publish_up IS NULL THEN s.publish_up
WHEN NOT e.publish_up IS NULL THEN e.publish_up
ELSE m.publish_up AS `publish_up`,
CASE
WHEN NOT s.state IS NULL THEN s.state
WHEN NOT e.state IS NULL THEN e.state
ELSE m.state AS `state`
FROM z_news_master m
LEFT JOIN z_news_spanish s ON m.id = s.reference_id
LEFT JOIN z_news_english e ON m.id = e.reference_id
WHERE m.created_by = 17152
ORDER by m.id DESC
GROUP BY m.id
修改强>
Per Paul Spiegel的评论这是一个更短的版本:
SELECT
COALESCE(s.id, e.id, m.id) AS `id`,
COALESCE(s.reference_id, e.reference_id, m.reference_id) AS `reference_id`,
COALESCE(s.title, e.title, m.title) AS `title`,
COALESCE(s.created_by, e.created_by, m.created_by) AS `created_by`,
COALESCE(s.publish_up, e.publish_up, m.publish_up) AS `publish_up`,
COALESCE(s.state, e.state, m.state) AS `state`
FROM z_news_master m
LEFT JOIN z_news_spanish s ON m.id = s.reference_id
LEFT JOIN z_news_english e ON m.id = e.reference_id
WHERE m.created_by = 17152
ORDER by m.id DESC
GROUP BY m.id