我不明白为什么这个查询不起作用

时间:2014-12-24 18:30:22

标签: mysql

我有很多经典的多对多关系。像这样:表groupe

+---------------+---------------------+------+-----+---------+----------------+
| Field         | Type                | Null | Key | Default | Extra          |
+---------------+---------------------+------+-----+---------+----------------+
| id            | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| val           | text                | NO   | UNI | NULL    |                |
+---------------+---------------------+------+-----+---------+----------------+

groupe_valeur

+-----------+---------------------+------+-----+---------+-------+
| Field     | Type                | Null | Key | Default | Extra |
+-----------+---------------------+------+-----+---------+-------+
| groupe_id | bigint(20) unsigned | NO   | PRI | NULL    |       |
| valeur_id | bigint(20) unsigned | NO   | PRI | NULL    |       |
+-----------+---------------------+------+-----+---------+-------+

表格valeur

+---------------+---------------------+------+-----+---------+----------------+
| Field         | Type                | Null | Key | Default | Extra          |
+---------------+---------------------+------+-----+---------+----------------+
| id            | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| val           | text                | NO   | MUL | NULL    |                |
+---------------+---------------------+------+-----+---------+----------------+

我添加了groupe 3行:一行用于prenom(=英文名称),一行用于男性masculin,另一行用于女性feminin

SELECT g.id, g.val
FROM groupe g
WHERE g.val='prenom' OR g.val='masculin' OR val='feminin';
+---------+----------+
| id      | val      |
+---------+----------+
| 6041745 | feminin  |
| 6041744 | masculin |
| 6041746 | prenom   |
+---------+----------+

我有男性和女性的所有法国名字。对于每个名称,我在groupevaleur之间创建了两个“链接”:一个值为prenom,另一个值为masculinfeminin。 让我们试试Erika

SELECT g.val, gp.*, v.val
FROM groupe g 
JOIN groupe_valeur gp ON gp.groupe_id=g.id
JOIN valeur v ON v.id=gp.valeur_id
WHERE v.val like 'Erika';
+---------+-----------+-----------+-------+
| val     | groupe_id | valeur_id | val   |
+---------+-----------+-----------+-------+
| feminin |   6041745 |   6095430 | Erika |
| prenom  |   6041746 |   6095430 | Erika |
+---------+-----------+-----------+-------+

这似乎很好。现在我想选择一个随机值。

SELECT val
FROM valeur v
JOIN groupe_valeur gv ON v.id=gv.valeur_id
WHERE gv.groupe_id IN (
    SELECT id FROM groupe WHERE val IN ('prenom', 'masculin')
)
ORDER BY RAND() LIMIT 30;

+------------+
| val        |
+------------+
| Ziad       |
| Rosanna    |
| Vincent    |
| Soraya     |
| Gabriela   |
| Florent    |
+------------+

这不起作用,给我男性和女性的名字!我做错了什么?

3 个答案:

答案 0 :(得分:0)

如果我理解你的问题,这是你的问题:

SELECT id FROM groupe WHERE val IN ('prenom', 'masculin')

IN运算符将接受“masculin”或“prenom”的组值,并且所有值都是prénoms,ergo,此子查询将返回所有名字!我建议您在数据库上执行该查询,并检查结果。

 SELECT id FROM groupe WHERE val = 'masculin'

应该可以工作,或者甚至更好地重写您的查询:

SELECT val
FROM valeur v
JOIN groupe_valeur gv ON v.id=gv.valeur_id
JOIN groupe g ON gv.groupe_id = g.id
WHERE g.val = 'masculin'
ORDER BY RAND() LIMIT 30;

如果您打算添加新组(例如,名字为“nom”),您可以这样做:

SELECT val
FROM valeur v
JOIN groupe_valeur gv ON v.id=gv.valeur_id
JOIN groupe g1 ON gv.groupe_id = g.id
JOIN groupe g2 ON gv.groupe_id = g.id
WHERE g1.val = 'masculin'
AND g2.val = 'prenom'
ORDER BY RAND() LIMIT 30;

答案 1 :(得分:0)

也许是这样的:首先得到30个随机男性,然后得到男性的名字:

SELECT v.val 
FROM valeur v
JOIN (
   SELECT gv.valeur_id
   FROM groupe_valeur gv 
   JOIN groupe g ON g.id = gv.groupe_id  and g.val = 'masculin '
   ORDER BY RAND() LIMIT 30
) as der ON der.valeur_id = v.id
JOIN groupe_valeur gv2 ON gv2.valeur_id = v.id 
JOIN groupe g2 ON g2.id = gv2.groupe_id and g2.val='prenom'

答案 2 :(得分:0)

丹的回答让我走上正轨 - 即使他的答案不正常 - 请参阅我的评论。以下是我可以在Php的foreach()循环中使用的工作解决方案,以添加尽可能多的group值,其作用类似于我想要的过滤器:

SELECT v.val
FROM valeur v
JOIN (
   SELECT gv.valeur_id
   FROM groupe_valeur gv
   JOIN groupe g ON g.id = gv.groupe_id  and g.val = 'feminin'
) as g0 ON g0.valeur_id = v.id
JOIN (
   SELECT gv.valeur_id
   FROM groupe_valeur gv
   JOIN groupe g ON g.id = gv.groupe_id  and g.val = 'prenom'
) as g1 ON g1.valeur_id = v.id
ORDER BY RAND() LIMIT 50;