在MySQL中从多个表中选择,然后加入两者

时间:2014-10-10 11:40:51

标签: mysql sql phpmyadmin

假设我的数据库结构有点像这样:

CREATE TABLE person (
    idPerson    INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    name        VARCHAR(50)
);

CREATE TABLE detailTypes (
    type            INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    field           VARCHAR(50)
);

CREATE TABLE details (
    idPerson        INT NOT NULL,
    idDetailType    INT NOT NULL,
    value           VARCHAR(50)
);

有了这些数据:

|----------|---------|
| idPerson | Name    |
|----------|---------|
| 1        | Tom     |
| 2        | Dick    |
| 3        | Harry   |
|----------|---------|

|----------|----------|
| type     | field    |
|----------|----------|
| 1        | Diet     |
| 2        | Hat size |
|----------|----------|

|----------|------|------------|
| idPerson | type | value      |
|----------|------|------------|
| 1        | 1    | Vegetarian |
| 1        | 2    | Medium     |
| 2        | 2    | Small      |
|----------|------|------------|

我想要一个看起来像这样的结果:

|----------|----------|------------|
| Name     | field    | value      |
|----------|----------|------------|
| Tom      | Diet     | Vegetarian |
| Tom      | Hat Size | Medium     |
| Dick     | Diet     | NULL       |
| Dick     | Hat Size | Small      |
| Harry    | Diet     | NULL       |
| Harry    | Hat Size | NULL       |
|----------|----------|------------|

我想,如果我错了,请纠正我,应该达到这个目标的查询应该是这样的:

SELECT name, field, value
FROM person p, detailTypes t
LEFT JOIN details d
    ON p.idPerson = d.idPerson AND t.type = d.type

但MySQL(5.5.32)/ PHPMyAdmin抱怨'on clause'中的“未知列'p.idPerson'”。你可以转到:

SELECT name, field, value
FROM detailTypes t, person p
LEFT JOIN details d
    ON p.idPerson = d.idPerson AND t.type = d.type

并且它有同样的抱怨,除了t.type现在是未知的。

当前解决方案是 [shudder] 嵌套查询,如下所示:

SELECT name, field, value
FROM (
    SELECT type, field, idPerson
    FROM person p, detailsType t
) pt
LEFT JOIN pt.idPerson = p.idPerson AND pt.type = t.type

这是MySQL的已知问题吗?这是我的第一次查询是完全错误的吗?我能以更好的方式做到吗?因为它对我来说似乎不对....

4 个答案:

答案 0 :(得分:1)

我还没有评论的状态,所以我在这里写。 您是否尝试将'p'和't'值设置为表的主键?

答案 1 :(得分:1)

没有"类型"任何表格中的字段。你打算用idDetailType吗?请尝试以下方法:

SELECT * 
FROM detailTypes t 
JOIN person p 
LEFT JOIN details d ON p.idPerson = d.idPerson AND t.idDetailType = d.idDetailType

然后优化结果以避免使用那令人讨厌的*

PD:字段和值是保留关键字。由于这个原因,可能会有一些意想不到的行为。

答案 2 :(得分:0)

您只需使用一个查询

即可
    SELECT p.name, t.field, dt.value
    FROM person p INNER JOIN detailTypes dt ON p.idPerson=dt.idPerson
    LEFT JOIN details d ON d.idDetailType=dt.idDetailType

答案 3 :(得分:0)

试试这个:

SELECT temp.name, temp.typeName as field, d.value
FROM (select * from person, detailTypes) temp
 LEFT JOIN details d
ON temp.idPerson = d.idPerson AND temp.typeName = d.idDetailType