如何从多个表组合一个记录

时间:2012-08-22 15:58:44

标签: mysql join group-by record group-concat

我有两节课和课程。它是一对多的比例,因为每节课可以分为1个或更多主题,导致类似“名称”主题:数学,科学,社会研究

这将返回3条记录:
姓名,数学
姓名,科学 名称,社会研究

这导致我循环并合并并弄乱我的搜索计数
我怎样才能获得所有三张唱片呢?所以我的搜索计数是准确的,我不需要额外的PHP代码来检查名称是否相同并收集额外的主题?

我试过基本的

SELECT * FROM lesson INNER JOIN subjects ON subject.id = lesson.subject

但这导致3个条目

修改
我的查询比我领导的要复杂得多。我有一个中间表,跟踪上面的两个表及其关系。这个查询用于搜索。这就是我所拥有的。

SELECT name, subject        
FROM lesson As l
INNER JOIN lesson_sub As ls
  ON ls.lesson_id = l.id
INNER JOIN subjects As s
  ON s.id = ls.subject_id
WHERE CONCAT(l.name, s.subject) LIKE '%KEYWORD%' AND s.id = SUBJECT_ID

3 个答案:

答案 0 :(得分:2)

您可以将GROUP_CONCAT()函数与JOIN查询一起使用:

http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat

  

GROUP_CONCAT(表达式)

     

此函数返回带有连接非NULL的字符串结果   一组中的值。如果没有非NULL值,则返回NULL。   完整语法如下:

     

GROUP_CONCAT([DISTINCT] expr [,expr ...]                [ORDER BY {unsigned_integer | col_name | EXPR}                    [ASC | DESC] [,col_name ...]]                [SEPARATOR str_val])

     

的MySQL> SELECT student_name,        - > GROUP_CONCAT(test_score)        - >来自学生        - > GROUP BY student_name;

     

或者:

     

的MySQL> SELECT student_name,        - > GROUP_CONCAT(DISTINCT test_score        - > ORDER BY test_score DESC SEPARATOR'')        - >来自学生        - > GROUP BY student_name;

所以:

SELECT lesson.name, GROUP_CONCAT(subjects.name SEPARATOR ', ')
    FROM lesson JOIN subjects ON (subject.id = lesson.subject)
    GROUP BY lesson.name;

<强> TEST

CREATE TABLE lesson ( name varchar (20), subject integer );
CREATE TABLE subjects ( id integer, name varchar(20) );

INSERT INTO subjects VALUES ( 1, 'Math' ), ( 2, 'Physics' ), ( 3, 'Chemistry' );

INSERT INTO lesson VALUES ( 'Lesson A', 1 );
INSERT INTO lesson VALUES ( 'Lesson A', 2 );
INSERT INTO lesson VALUES ( 'Lesson A', 3 );
INSERT INTO lesson VALUES ( 'Lesson B', 2 );
INSERT INTO lesson VALUES ( 'Lesson B', 3 );
INSERT INTO lesson VALUES ( 'Lesson C', 1 );

SELECT lesson.name, GROUP_CONCAT(subjects.name SEPARATOR ', ')
    FROM lesson JOIN subjects ON (subjects.id = lesson.subject)
    GROUP BY lesson.name;

+----------+--------------------------------------------+
| name     | GROUP_CONCAT(subjects.name SEPARATOR ', ') |
+----------+--------------------------------------------+
| Lesson A | Math, Chemistry, Physics                   |
| Lesson B | Chemistry, Physics                         |
| Lesson C | Math                                       |
+----------+--------------------------------------------+
3 rows in set (0.00 sec)

更复杂的测试(使用中间表)

CREATE TABLE lesson ( id integer, name varchar (20) );
CREATE TABLE subjects ( id integer, name varchar(20) );
CREATE TABLE lesson_sub ( lesson_id integer, subject_id integer );

INSERT INTO subjects VALUES ( 1, 'Math' ), ( 2, 'Physics' ), ( 3, 'Chemistry' );
INSERT INTO lesson VALUES ( 1, 'Lesson A' ), ( 2, 'Lesson B' ), ( 3, 'Lesson C' );

INSERT INTO lesson_sub VALUES (1,1), (1,2),(1,3),(2,2),(2,3),(3,1);

SELECT lesson.name, GROUP_CONCAT(subjects.name SEPARATOR ', ') AS subjects
    FROM lesson_sub JOIN lesson ON ( lesson.id = lesson_sub.lesson_id )
                    JOIN subjects ON (subjects.id = lesson_sub.subject_id)
    WHERE CONCAT(lesson.name, subjects.name) LIKE '%Chem%'
    GROUP BY lesson.name;

SELECT name, subjects FROM (
    SELECT lesson.name, GROUP_CONCAT(subjects.name SEPARATOR ', ') AS subjects
    FROM lesson_sub JOIN lesson ON ( lesson.id = lesson_sub.lesson_id )
                    JOIN subjects ON (subjects.id = lesson_sub.subject_id)
    GROUP BY lesson.name ) AS lesson_clear
    WHERE CONCAT(name, subjects) LIKE '%Chem%';

+----------+--------------------------------------------+
| name     | GROUP_CONCAT(subjects.name SEPARATOR ', ') |
+----------+--------------------------------------------+
| Lesson A | Chemistry                                  |
| Lesson B | Chemistry                                  |
+----------+--------------------------------------------+
2 rows in set (0.00 sec)

+----------+--------------------------+
| name     | subjects                 |
+----------+--------------------------+
| Lesson A | Physics, Math, Chemistry |
| Lesson B | Physics, Chemistry       |
+----------+--------------------------+
2 rows in set (0.00 sec)

答案 1 :(得分:0)

为什么内连接,如果你只想要主题名称?

SELECT subject
FROM lesson

现在,如果您想要至少有一节课的科目,那么您可以简单地进行

SELECT DISTINCT subject
FROM lesson
INNER JOIN subjects ON subject.id = lesson.subject

答案 2 :(得分:0)

看起来你希望每个人有一条记录,即name

这是一种方法:

      SELECT name, count(*) subject_count
        FROM lesson 
  INNER JOIN subjects ON subject.id = lesson.subject
    GROUP BY name
    ORDER BY name

如果您需要按名称显示记录中显示的主题,请尝试以下操作:

      SELECT name, 
             count(*) subject_count,
             group_concat(subject) subjects
        FROM lesson 
  INNER JOIN subjects ON subject.id = lesson.subject
    GROUP BY name
    ORDER BY name