MySQL中的条件选择

时间:2012-02-15 15:30:18

标签: mysql sql select conditional

我正在处理一个mysql查询,它给我带来了麻烦!

情景:

我正在建立一个人们可以选择他们感兴趣的行业的网站(NOTIFY_INDUSTRY)。我加入选定的值并存储在数据库字段中。

示例:成员选择农业(id = 9)和石油和天然气(id = 13)。我以9-13加入它们并存储在数据库中。 用户可以选择多个行业,不限于两个行业。

此外,会员可以选择它所属的行业(COMPANY_INDUSTRY),也可以选择存储在数据库中的信息技术。

Sample table (members):

ID
EMAIL
COMPANY_NAME
COMPANY_INDUSTRY
NOTIFY_INDUSTRY

问题:

当新用户在网站上注册时,邮件(邮件每天发送)将发送给拥有新用户行业(COMPANY_INDUSTRY)作为其感兴趣行业之一的现有用户(NOTIFY_INDUSTRY)。

我做了什么:

$sql="select id, email
      from members
      where notify_industry in (
        select company_industry
        from members
        where datediff($today, date_activated) <= 1)"

这不会选择合适的成员,我不知道正确的方法

编辑 - 当前输出的确切问题:

不会返回任何行,即使它应该。

假设新用户的company_industry是9,并且现有用户有notify_industry:10-9-20;它旨在返回现有成员的电子邮件,因为新成员属于现有成员感兴趣的类别;但我得到了空白

5 个答案:

答案 0 :(得分:12)

正如@Shiplu指出的那样,这主要是一个规范化问题。尽管有些人似乎认为,多值列的谋杀试图做对。

您的基本问题是:
您有成员,他们对一个或多个公司/行业感兴趣,属于一个或多个行业。您的表结构可能应该以:

开头
Industry
===============
id  -- autoincrement
name  -- varchar

Company
==============
id  -- autoincrement
name  -- varchar

Company_Industry
===============
companyId  -- fk reference to Company.id
industryId  -- fk reference to Industry.id

Member
===============
id  -- autoincrement
name  -- varchar
email  -- varchar

Member_Interest_Industry
=========================
memberId  -- fk reference to Member.id
industryId  -- fk reference to Industry.id

Member_Interest_Company
========================
memberId  -- fk reference to Member.id
companyId  -- fk reference to Company.id

要让所有公司成员对(直接或通过行业)感兴趣,您可以运行以下内容:

SELECT a.name, a.email, c.name
FROM Member as a
JOIN Member_Interest_Company as b
ON b.memberId = a.id
JOIN Company as c
ON c.id = b.companyId
WHERE a.id = :inputParm
UNION 
SELECT a.name, a.email, d.name
FROM Member as a
JOIN Member_Interest_Industry as b
ON b.memberId = a.id
JOIN Company_Industry as c
ON c.industryId = b.industryId
JOIN Company as d
ON d.id = c.companyId
WHERE a.id = :inputParm

答案 1 :(得分:8)

您应该重新设计表格,正如其他人所建议的那样。

但是,除此之外,你可以做到这一点:

SET sql_mode = 'ANSI';

    SELECT notify_members.id, notify_members.email
      FROM members notify_members
INNER JOIN members new_members
     WHERE CURRENT_DATE - new_members.date_activated <= 1
           AND
           new_members.company_industry RLIKE ('[[:<:]](' || REPLACE(notify_members.notify_industry, '-', '|') || ')[[:>:]]');

呸。基本上,您将9-13转换为MySQL regular expression [[:<:]](9|13)[[:>:]],其匹配91313-27-61等,但不匹配{ {1}}等。 (这也支持复合的COMPANY_INDUSTRY字段。)

答案 2 :(得分:0)

使用连接SQL语法而不是样式中的select。 您需要将成员表连接到自身。

目前:

select id, email 
from members where notify_industry in 
  (select company_industry 
          from members 
           where datediff($today, date_activated) <= 1
  )

使用此风格:

select m1.id, m1.email 
from members m1 
inner join members m2 on m1.company_industry = m.notify_industry
where datediff($today, m2.date_activated) <= 1

请注意对m1和m2使用别名有助于了解返回的ID和电子邮件。

答案 3 :(得分:0)

这可能会有点难看,但您可以尝试以下

警告这将使笛卡儿产品值得任何疯狂科学家

SELECT NotifyIndustry.id,NotifyIndustry.email
FROM
(
    SELECT CONCAT('-',COMPANY_INDUSTRY,'-') company FROM members
    WHERE datediff($today, date_activated) <= 1)"
) CompanyIndustry
INNER JOIN
(
    SELECT CONCAT('-', NOTIFY_INDUSTRY,'-') who_to_notify
    FROM members
) NotifyIndustry
ON LOCATE(company,who_to_notify)>0;

答案 4 :(得分:0)

可能不是最快的查询,但这应该做的工作:

select m_to_notify.id, m_to_notify.email
from members m_to_notify
join members m_new_member
     on '-' || m_to_notify.notify_industry || '-'
     like '%-' || m_new_member.company_industry || '-%'
where datediff($today, m_new_memberdate_activated) <= 1)