4

我一直在尝试删除相交,因为 mysql 不支持它。如果有人可以提供一些指示,那将非常有帮助。

SELECT *, DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(dob, '%Y') - (DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(dob, '00-%m-%d')) AS age 
FROM user U, user_utilisation UU 
WHERE U.id_user = UU.id_user AND cp >= 1 AND cp <= 3000 AND sexe = 'M' AND UU.id_mailing = 6 
GROUP BY U.id_user 
HAVING age >= 1 AND age <= 100 
ORDER BY nom, prenom

INTERSECT 

SELECT *, DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(dob, '%Y') - (DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(dob, '00-%m-%d')) AS age 
FROM user U, user_utilisation UU 
WHERE U.id_user = UU.id_user AND cp >= 1 AND cp <= 3000 AND sexe = 'M' AND UU.id_mailing = 7 
GROUP BY U.id_user 
HAVING age >= 1 AND age <= 100 
ORDER BY nom, prenom

我尝试使用JOIN(s),但这是我现在所拥有的:

SELECT *, DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(naissance, '%Y') - (DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(naissance, '00-%m-%d')) AS age 
FROM user U, user_utilisation UU 
WHERE U.id_user = UU.id_user AND cp >= 1 AND cp <= 3000 AND sexe = 'M' 
    AND UU.id_user IN (select id_user from user_utilisation where id_mailing = 6 OR id_mailing = 7) 
HAVING age >= 1 AND age <= 100 
ORDER BY nom, prenom

但是通过删除GROUP BY我看到查询选择了 2 条记录 where id_mailing = 1,而GROUP BY隐藏了错误的记录。我很确定这可能会导致问题...

user_utilisation只有三个字段id_user,id_mailingdate.

4

3 回答 3

2

解释您的查询,在我看来:

  1. 您希望获得所有参与 mailing_id 6 和 7 的用户(这就是您这样做的原因INTERSECT,对吗?)。
  2. 您希望按条件限制这些用户并执行年龄计算。

如果我对您的意图的解释是正确的(完全不确定是这种情况!),您根本不需要INTERSECT,您应该能够根据您想要的标准简单地选择您想要的用户,并限制参与这两者通过以下方式邮寄 6 和 7 JOIN

SELECT *, DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(dob, '%Y') - (DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(dob, '00-%m-%d')) AS age 
FROM user U
INNER JOIN user_utilisation UU on U.id_user = UU.id_user and UU.mailing_id = 6
INNER JOIN user_utilisation UU2 on U.id_user = UU2.id_user and UU2.mailing_id = 7
WHERE cp >= 1 AND cp <= 3000 AND sexe = 'M' 
HAVING age >= 1 AND age <= 100 
ORDER BY nom, prenom
于 2013-01-21T17:04:42.357 回答
1

您可以尝试以下方法:

SELECT *
  FROM
      (SELECT *
            , DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(dob, '%Y') - (DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(dob, '00-%m-%d')) AS age 
        FROM user U
             INNER JOIN user_utilisation UU 
                     ON U.id_user = UU.id_user
        WHERE cp >= 1 AND cp <= 3000 
              AND sexe = 'M'
              AND UU.id_mailing = 6 
        GROUP BY U.id_user 
        HAVING age >= 1 AND age <= 100) QUERY1
 WHERE EXISTS(SELECT *
            , DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(dob, '%Y') - (DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(dob, '00-%m-%d')) AS age 
        FROM user U
             INNER JOIN user_utilisation UU 
                     ON U.id_user = UU.id_user
        WHERE cp >= 1 AND cp <= 3000 
              AND sexe = 'M'
              AND UU.id_mailing = 7
              AND U.id_user = QUERY1.id_user
        GROUP BY U.id_user 
        )
ORDER BY nom, prenom

上面查询中的技巧是 WHERE EXISTS( ... ) 子句充当过滤器,类似于您之前使用的 INTERSECT。这个想法是,您将只想从查询 QUERY1 中选择满足条件的记录,即 EXITS 子句中的查询中至少有一条记录,其条件是 id_user 与 QUERY1 查询中的 id_user 相同..我希望这有点道理..

如果您提供 User 表的结构,我可能会为您稍微调整一下。顺便说一句,使用那些笼统的 SELECT * 语句不是一个好主意..

于 2013-01-21T16:57:09.937 回答
0

我认为您可以简化查询。它有几个好奇心。首先,查询没有使用正确的连接语法。其次,查询使用该having子句只是为了过滤来自select. 在这种情况下,我建议使用子查询。

看起来您正在尝试获取两个“组”中的用户,这些用户由两个非常相似的查询定义(只有where子句不同)。以下可能是您正在寻找的内容:

select t.*
from (SELECT *, DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(dob, '%Y') - (DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(dob, '00-%m-%d')) AS age,
             (case when cp >= 1 AND cp <= 3000 AND sexe = 'M' AND UU.id_mailing = 6 then 'FirstGroup'
                   when cp >= 1 AND cp <= 3000 AND sexe = 'M' AND UU.id_mailing = 7 then 'SecondGroup'
              end) as thegroup
      FROM user U join user_utilisation UU 
           on U.id_user = UU.id_user
     ) t
where thegroup is not null and age between 1 and 100
GROUP BY U.id_user
having max(thegroup) <> min(thegroup)
ORDER BY nom, prenom

having子句是表示用户在两个组中的简写方式。

于 2013-01-21T17:19:21.360 回答