根据另一行的值选择一行

时间:2013-08-03 19:45:01

标签: mysql database-design relational-database

应用目标

通过GCM从零售商向注册客户发送消息

数据库架构

我有一个customers表和一个相关的customers_realtions表,其中包含以下字段:idcustomerIDretailerIDisBlocked < / p>

要求的结果

客户可以注册特定零售商或通配符(所有这些)。

如果有人为所有零售商注册,他可以选择阻止特定零售商发送未来消息,从而有效地创建黑名单。

每种状态的数据库值

  1. 当客户注册单个零售商retailerID时,会分配零售商ID。
  2. 当客户注册所有零售商retailerID等于1时。
  3. 当客户阻止零售商时,有两种选择:

    一个。如果他在isBlocked字段更新为1(真实)之前注册到此特定零售商

    湾如果他在为该零售商创建新行之前向所有零售商注册,并且isBlocked设置为1(真)

  4. 挑战

    发送邮件时,SELECT查询应包括零售商ID为1且 的客户在retailerID等于1时发送isBlocked

    例如,在这种情况下

    id  customerID  retailID    isBlocked
    129 46          111                 1
    128 46          1                   0
    

    即使零售商ID为111

    ,我也不希望选择客户

    我的尝试

    SELECT * FROM customers_relations 
                  WHERE 
                    (retailID=111 
                  OR 
                    (retailID=1
                    AND 
                    (SELECT isBlocked FROM `customers_relations` WHERE customerID=46 AND retailID=111)=0))
                  AND
                    NOT isBlocked 
    

    问题

    虽然这适用于我提前知道ID的单个客户,但我正在努力想办法为多个客户编写类似的查询。

1 个答案:

答案 0 :(得分:1)

我认为这是一个聚合查询。您希望查看未为客户阻止的所有行,并确定零售商111是否可用或所有零售商是否可用:

SELECT customerId
FROM customers_relations cr
WHERE isBlocked = false
GROUP BY customerId
HAVING MAX(retailId = 111) > 0 OR
       MAX(retailId = 1) > 0;

我注意到您的问题实际上是在有人被阻止时在customer_relations中创建行。以上假设有一行。要处理任何行上的块会导致阻塞的情况,那么:

SELECT customerId
FROM customers_relations cr
GROUP BY customerId
HAVING (MAX(retailId = 111) > 0 OR
        MAX(retailId = 1) > 0
       ) AND
       MAX(retailId = 111 AND isblocked = true) = 0;