SQL查询组合两个表,同时还显示一个表中的所有记录

时间:2016-04-02 17:35:55

标签: mysql sql

我正在运行以下查询,尝试在论坛中获取所有类别,并发布最新主题。有些类别尚未发布任何主题,并希望也返回这些类别。

SELECT cat_id,cat_name,cat_description, Null as topic_date, 
       Null as topic_subject 
FROM categories 
UNION ALL 
SELECT cat_id, cat_name, cat_description, topic_date, topic_subject 
FROM categories, topics t  
WHERE t.topic_cat=cat_id  AND topic_id IN
  (SELECT topic_id FROM 
    (SELECT topic_id FROM 
      (SELECT topic_id, topic_subject, MAX(topic_date) AS 'recent'
       FROM topics  
       GROUP BY topic_Cat 
       ) a
    ) b
  );

此查询返回以下结果: -

+--------+-----------+---------+------------+---------------+
| cat_id | cat_name  | cat_des | topic_date | topic_subject |
+--------+-----------+---------+------------+---------------+
|      1 |  T20 World|  Posts1 | NULL                | NULL |
|      2 |  Test     |  delete1| NULL                | NULL |
|      3 |  Test 2   |  txt    | NULL                | NULL |
|      1 |  T20 World|  Posts1 | 2016-04-01 01:54:01 | test |
|      2 |  Test     |  delete1| 2016-04-01 03:05:58 | test |
+--------+---------------+------------------------+--------+

正如您所看到的,cat_id 3还没有帖子并且根据需要返回!但是重复了cat_id 1& 2。

我正在尝试删除重复,我不确定我缺少什么

4 个答案:

答案 0 :(得分:1)

UNION ALL替换为UNION。后者删除了重复项。

但是,根据您的代码,您可能正在尝试LEFT OUTER JOIN,因此您应该查看OUTER JOIN上的一些教程

答案 1 :(得分:1)

您需要的是一个左外连接子句,用于将主题的结果加入类别。在这些方面的某个地方:

SELECT c.cat_id, c.cat_name, c.cat_description, 
       max(t.topic_date), t.topic_subject
FROM categories c LEFT OUTER JOIN topics t ON t.topic_cat=c.cat_id
GROUP BY c.cat_id, c.cat_name, c.cat_description, t.topic_subject;

答案 2 :(得分:0)

SQL上有点生疏,但这样的事情应该有效:

SELECT
  cat.cat_id, cat.cat_name, cat.cat_desc, topic.topic_date, topic.topic_subject
FROM
  categories AS cat
LEFT OUTER JOIN (
  SELECT
    topics.topic_date, topics.topic_subject
  FROM
    topics
  ORDER BY
    topics.topic_date DESC
  LIMIT
    1
  )
  AS topic ON topic.cat_id = cat.cat_id;

答案 3 :(得分:0)

最终对我有用的是将union的结果作为派生表转换为另一个select语句,该语句按cat_id对结果进行分组,从而删除重复项和空值。

我还在UNION周围交换了两个select语句,所以首先完成过滤后的一个,然后是显示所有行的那个。

感谢您的反馈!

SELECT * FROM(SELECT * FROM(SELECT cat_id,cat_name,cat_description,topic_id,topic_subject,MAX(topic_date) 来自类别,主题的AS'topic_date'主题WHERE topic_cat = cat_id GROUP BY topic_Cat)UNION SELECT cat_id,cat_name,cat_description, NULL为topic_id,Null为topic_date,Null为topic_subject FROM categories)b GROUP BY cat_name;