表将列名称连接到列值

时间:2015-01-19 03:44:48

标签: mysql

我看过很多相似的问题,但我似乎找不到符合我需要的问题......

我有以下2个表格:

表1(ambro_awards_categories):

id  cat_name    category
1   cat1        Would most likely know how to fondue an ant
2   cat2        Most Likely to survive a nuclear winter
3   cat3        Most Likely to survive a nuclear winter
4   cat4        Category 4
5   cat5        Category 5
6   cat6        Category 6
7   cat7        Category 7
8   cat8        Category 8
9   cat9        Category 9

表2(ambro_awards):

id  voter_name          cat1                cat2                cat>>>      date
1   Cavey Charlesworth  Cavey Charlesworth  Cavey Charlesworth  ...         2015-01-18 00:00:00
2   Lynn Wylder         Lynn Wylder         Lynn Wylder         ...         2015-01-18 00:00:00
3   Lynn Wylder         Peter Parker        Batman              ...         2015-01-18 00:00:00
etc

我想要做什么(我完全接受可能有更好的方法在那里做到这一点)是将所有东西连接在一起,加入cat1,cat2等等。这样我就可以修改了类别名称为更长,更具描述性的名称,而不会延长第二个表格。

这意味着在表1的cat_name值上执行表2中的cat1,cat2列名称。

所需的结果如下:

Would most likely know how to fondue an ant (ie "Category 1")
     name 1
     name 2
     name 3
     name 4... etc

Most Likely to survive a nuclear winter (ie "Category 2")
     name 1
     name 2
     name 3
     name 4... etc

Most likeley to succeed (ie "Category 3")
     name 1
     name 2
     name 3
     name 4... etc

那种事......

如果只是简单地将多个名称添加到1表中,我会这样做,但认为这可能有点错误......希望能够做到以上情况,但后来遇到了问题... < / p>

点Pj。

1 个答案:

答案 0 :(得分:1)

至少可以说这个设计远非理想,但为了回答你的问题,据我所知,你不能连接第二个表的列名是列的值的表。 (你当然可以轻松地)。但是,我认为您之后可以使用当前架构以这种方式编写:

CREATE VIEW ambro_full_data AS
SELECT a.id as aid, c.id as cid, c.cat_name,
    CASE c.cat_name
        WHEN 'cat1' THEN a.cat1
        WHEN 'cat2' THEN a.cat2
        WHEN 'cat3' THEN a.cat3
        WHEN 'cat4' THEN a.cat4
        WHEN 'cat5' THEN a.cat5
        WHEN 'cat6' THEN a.cat6
        WHEN 'cat7' THEN a.cat7
        WHEN 'cat8' THEN a.cat8
        WHEN 'cat9' THEN a.cat9
    END as name,
    c.category,
    a.date
FROM ambro_awards_categories c
  CROSS JOIN ambro_awards a;

例如:

mysql> SELECT name FROM ambro_full_data WHERE cid = 1;
+--------------------+
| name               |
+--------------------+
| Cavey Charlesworth |
| Lynn Wylder        |
| Peter Parker       |
+--------------------+
3 rows in set (0.00 sec)

mysql> SELECT category,name FROM ambro_full_data ORDER BY cid;
+---------------------------------------------+--------------------+
| category                                    | name               |
+---------------------------------------------+--------------------+
| Would most likely know how to fondue an ant | Cavey Charlesworth |
| Would most likely know how to fondue an ant | Lynn Wylder        |
| Would most likely know how to fondue an ant | Peter Parker       |
| Most Likely to survive a nuclear winter     | Lynn Wylder        |
| Most Likely to survive a nuclear winter     | Batman             |
| Most Likely to survive a nuclear winter     | Cavey Charlesworth |
| Most Likely to survive a nuclear winter     | Lynn Wylder        |
| Most Likely to survive a nuclear winter     | Cavey Charlesworth |
| Most Likely to survive a nuclear winter     | Lynn Wylder        |
| Category 4                                  | Cavey Charlesworth |
| Category 4                                  | Lynn Wylder        |
| Category 4                                  | Lynn Wylder        |
| Category 5                                  | Lynn Wylder        |
| Category 5                                  | Lynn Wylder        |
| Category 5                                  | Cavey Charlesworth |
| Category 6                                  | Lynn Wylder        |
| Category 6                                  | Cavey Charlesworth |
| Category 6                                  | Lynn Wylder        |
| Category 7                                  | Cavey Charlesworth |
| Category 7                                  | Lynn Wylder        |
| Category 7                                  | Lynn Wylder        |
| Category 8                                  | Lynn Wylder        |
| Category 8                                  | Lynn Wylder        |
| Category 8                                  | Cavey Charlesworth |
| Category 9                                  | Cavey Charlesworth |
| Category 9                                  | Lynn Wylder        |
| Category 9                                  | Lynn Wylder        |
+---------------------------------------------+--------------------+
27 rows in set (0.00 sec)

但是当你添加一列时,你需要相应地更新视图。

然而,更好的设计是使用这样的表格:

CREATE TABLE ambro_awards (id ..., voter_name ..., date ...);(注意没有catN列)

CREATE TABLE ambro_awards_categories (id ..., category ...);(注意不需要cat_name列)

CREATE TABLE ambro_awards_and_categories (a_id INTEGER NOT NULL, c_id INTEGER NOT NULL, name VARCHAR(<suitable length here>) NOT NULL, PRIMARY KEY (a_id, c_id), FOREIGN KEY (a_id) REFERENCES ambro_awards (id), FOREIGN_KEY (c_id) REFERENCES ambro_awards_categories (id));

使用您的示例数据,后一个表格如下:

a_id    c_id    name
1       1       Cavey Charlesworth
1       2       Cavey Charlesworth
1       3       Cavey Charlesworth
2       1       Lynn Wylder
2       2       Lynn Wylder
2       3       Lynn Wylder
3       1       Lynn Wylder
3       2       Peter Parker
3       3       Batman

通过这种方式,您可以拥有任意数量的类别,而无需为每个类别创建列。然后,您可以执行相应的JOIN来提取与上面相同的数据,例如

SELECT c.category, ac.name FROM ambro_awards_and_categories ac JOIN ambro_awards_categories c ON c.id = ac.c_id;

类似的连接可用于从另一个表中提取其他数据。例如,你原来的ambro_awards第1行可以用

之类的东西提取到多行

SELECT a.id, a.voter_name, a.date, ac.name FROM ambro_awards a JOIN ambro_awards_and_categories ac ON ac.a_id = a.id WHERE a.id = 1;

这是SQL中非常标准的做法,如果充分使用,也可以解决您的问题。