如果相同uID的其他行具有特定单元格值,则查询SELECT uID

时间:2012-07-23 06:07:48

标签: php mysql codeigniter

我正在尝试构建基于PHP的Web软件,我遇到了一个我不知道解决方案语法的问题。

基本上,我有两张桌子:

+-------------+     +---------------+
| Certs       |     | Clients       |
+-------------+     +---------------+
| userID      |     | eID           |
| prodID      |     | prods         |
| prodName    |     +---------------+
+-------------+

此处,个人购买的每件商品都由其唯一的用户ID和产品的独特产品存储。

客户就像是卖家,他们自己拥有不同的ID,而且是一串逗号熟练的产品ID。

certs表中的示例行如下:

userID  |  prodID  |  prodName
------------------------------
9000    |  42      |  Pen     
4234    |  54      |  Pencil
9000    |  54      |  Pencil

示例客户行如下:

eID  |  prods
-------------
595  |  42,54

现在,我需要形成一个查询,返回已购买特定卖家所有产品的所有用户ID。

例如,对于卖家ID 595,它应该返回9000,因为userID 9000已经购买了42和54.

为方便起见,可以修改表格结构,但由于其他技术原因,我无法创建与其卖家相关的标准化产品列表。

任何帮助将不胜感激!感谢〜

注意:另一种方法是将卖家的产品列表保存在结果类型数组中。 然后 SELECT prodID FROM 证书 WHERE userID = x 最后检查是否,prodID的结果数组包含数组prods的所有元素。

1 个答案:

答案 0 :(得分:2)

试试这个解决方案:

SELECT a.userID
FROM certs a
INNER JOIN clients b ON b.eID = 595 AND FIND_IN_SET(a.prodID, b.prods) > 0
CROSS JOIN
(
    SELECT (LENGTH(prods) - LENGTH(REPLACE(prods, ',', ''))) + 1 AS prodcnt
    FROM clients
    WHERE eID = 595
) c
GROUP BY a.userID, c.prodcnt
HAVING COUNT(1) = c.prodcnt

工作原理:

CROSS JOIN
(
    SELECT (LENGTH(prods) - LENGTH(REPLACE(prods, ',', ''))) + 1 AS prodcnt
    FROM clients
    WHERE eID = 595
) c

这样做会在每一行附加特定卖家拥有的prodID数量。我们通过获取CSV列表的字符串长度并减去相同CSV列表的长度但没有逗号来计算它,并在差异中添加一个。例如:

字符串长度54,234,436”为10。

替换逗号:

字符串长度54234436”为8。

那么(10-8)+1 = 3。

列表中的三个项目。


我们使用FIND_IN_SET作为certsclients之间的联接条件,以确定prodID列表中是否存在prods

FIND_IN_SET基本上返回CSV列表中特定项目的从1开始的索引位置。例如:

FIND_IN_SET('54', '34,76,54,128') 

将返回3,因为54作为列表中的第三项存在。我们只需要检查它是否存在于连接条件的列表中,所以我们只检查它是否是> 0.如果该项目不在CSV列表中,则返回0.


一旦我们有特定客户的产品与笛卡尔联合计数,并且加入了表,中间结果集将如下所示:

a.userID  |  a.prodID  |  b.eID  |  b.prods  |  c.prodcnt
---------------------------------------------------------
9000      |  42        |  595    |  42,54    |  2
4234      |  54        |  595    |  42,54    |  2
9000      |  54        |  595    |  42,54    |  2

这些行中的每一行都满足连接条件。

然后我们按userID进行分组,以计算每userID行的行数。由于9000与c.prodcnt中的重复值具有相同的行数,因此返回该行。 userID 4234是适合的,因为只有一行满足连接条件。