Mysql - 三表查询

时间:2012-07-24 13:59:52

标签: mysql

我有三个表用于存储一些用户数据。

sub_domains(体验子域名转到此处。exp_idid中的exp匹配,domain_id中的id匹配misc 。如果用户有多个子域,user_idexp_id可以重复。

+-----------+---------+------+-----+---------+----------------+
| Field     | Type    | Null | Key | Default | Extra          |
+-----------+---------+------+-----+---------+----------------+
| id        | int(11) | NO   | PRI | NULL    | auto_increment |
| user_id   | int(50) | YES  |     | NULL    |                |
| domain_id | int(10) | NO   |     | NULL    |                |
| exp_id    | int(50) | YES  |     | NULL    |                |
+-----------+---------+------+-----+---------+----------------+

misc

+----------+--------------+------+-----+---------+----------------+
| Field    | Type         | Null | Key | Default | Extra          |
+----------+--------------+------+-----+---------+----------------+
| id       | int(11)      | NO   | PRI | NULL    | auto_increment |
| name     | varchar(100) | YES  |     | NULL    |                |
| category | varchar(255) | YES  |     | NULL    |                |
+----------+--------------+------+-----+---------+----------------+

exp

+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| id         | int(11)      | NO   | PRI | NULL    | auto_increment |
| user_id    | int(11)      | YES  |     | NULL    |                |
| job_type   | varchar(60)  | YES  |     | NULL    |                |
| experience | varchar(500) | YES  |     | NULL    |                |
| exp_title  | varchar(255) | YES  |     | NULL    |                |
| domain     | varchar(125) | YES  |     | NULL    |                |
| start      | varchar(20)  | YES  |     | NULL    |                |
| end        | varchar(20)  | YES  |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+

这是我从查询中获取数据的查询:

$query_str = "SELECT a.id, a.user_id, a.job_type, a.experience, a.exp_title, a.domain,     a.start, a.end, b.name
FROM exp a
JOIN misc b ON a.domain=b.id
WHERE a.user_id = ?";

我已经从misc获取了域名,但我也希望从misc获取每个子域名,但我不知道如何更改查询。

修改

我对此进行了一点研究并想出了这个:

$query_str = "SELECT a.id, a.user_id, a.job_type, a.experience, a.exp_title, a.domain, a.start, a.end, b.name,
(SELECT GROUP_CONCAT(domain_id) FROM sub_domains sd WHERE a.id=sd.exp_id) AS subs,
(SELECT GROUP_CONCAT(name) FROM misc WHERE id IN( subs ) ) AS subcats
FROM exp a
JOIN misc b ON a.domain=b.id
WHERE a.user_id = ?";

它几乎可以工作,子类的var_dump只返回name表中的第一个misc

5 个答案:

答案 0 :(得分:2)

这应该有效:

SELECT a.id, a.user_id, a.job_type, a.experience, a.exp_title, a.domain, a.start, a.end, b.name
FROM exp a
     INNER JOIN misc b 
         ON a.domain=b.id
     INNER JOIN sub_domains c
         ON a.id=c.exp_id
WHERE a.user_id = ?

答案 1 :(得分:2)

不确定自己到底发生了什么,但这可能会有所帮助。使用LEFT JOIN,因为您不强制执行外键。

select exp.id, exp.user_id, exp.job_type, exp.experience, exp.exp_title,
       exp.domain, exp.start, exp.end,
       GROUP_CONCAT(misc.name) as sub_domain_names
from exp
left join sub_domains
    on (exp.id = sub_domains.exp_id)
left join misc
    on (sub_domains.domain_id = misc.id)
where exp.user_id = ?
group by exp.id, exp.user_id, exp.job_type, exp.experience, exp.exp_title,
         exp.domain, exp.start, exp.end;

答案 2 :(得分:1)

只需扩展您当前的查询:

SELECT a.id, a.user_id, a.job_type, a.experience, 
       a.exp_title, a.domain, a.start, a.end, b.name, c.id
FROM exp a
JOIN misc b ON a.domain = b.id
JOIN sub_domains c ON c.domain_id = b.id
WHERE a.user_id = ?

答案 3 :(得分:1)

在研究了你的问题一段时间之后,我能够弄清楚你追求的是什么。

您可以尝试此解决方案:

SELECT    
    a.*, 
    b.name AS domain_name,
    c.subdomain_names
FROM
    exp a
LEFT JOIN 
    misc b ON a.domain = b.id
LEFT JOIN
(
    SELECT   aa.exp_id, GROUP_CONCAT(bb.name) AS subdomain_names
    FROM     sub_domains aa
    JOIN     misc bb ON aa.domain_id = bb.id
    GROUP BY aa.exp_id
) c ON a.id = c.exp_id
WHERE 
    a.user_id = ?

虽然如果user_id表中已经引用了sub_domains,我对user_id表中的exp列的原因感到有点困惑。对我来说,这似乎是一个可以消除的重复。

答案 4 :(得分:0)

我有同样的问题。由于您的查询很好并且运行良好。但是,您需要使用GROUP_CONCAT()方法显示所有名称。

不幸的是它只显示了名字。是吗?

请检查IN()条件,如果您手动将值放在IN

IN('1,2,3'),它还会显示您的名字。

解决方案: -

保持您的查询一致。但是将以下行与查询分开:

String query1= SELECT GROUP_CONCAT(domain_id) FROM sub_domains sd WHERE a.id=sd.exp_id

在执行主查询之前,先在DAO类(你的DAO方法)中运行此查询。

String中获取返回值,然后将该(query1)String放入主查询IN()

我从这种类型的DAO操作得到了我的预期答案。 希望它的帮助充分。

相关问题