从字段中检索逗号分隔的数据

时间:2010-03-12 19:54:03

标签: sql

我在PHP中创建了一个收集基本信息的表单。我有一个列表框,允许选择多个项目(即住房,租金,食物,水)。如果选择了多个项目,它们将存储在名为Needs的字段中,并以逗号分隔。

我已根据个人需求创建了一份报告。只有一个需要的人被正确地分类,但是具有多个人的人被完全按照传递给数据库的字符串(即住房,租金,食物,水)进行分类 - >这不是我想要的。

是否有办法使用SQL将每个需要的实例/事件计数为1来分隔此字段中的多个值,以便结果中不显示逗号分隔符?

2 个答案:

答案 0 :(得分:2)

您的数据库不在first normal form中。正如您实际遇到的那样,非规范化数据库的使用和查询将非常棘手。

通常,您应该至少使用以下结构。它仍然可以进一步规范化,但我希望这能让你朝着正确的方向前进:

CREATE TABLE users (
    user_id int,
    name    varchar(100)
); 

CREATE TABLE users_needs (
    need     varchar(100),
    user_id  int
);

然后你应该按如下方式存储数据:

-- TABLE: users

+---------+-------+
| user_id | name  |
+---------+-------+
|       1 | joe   | 
|       2 | peter | 
|       3 | steve | 
|       4 | clint | 
+---------+-------+

-- TABLE: users_needs

+---------+----------+
| need    | user_id  |
+---------+----------+
| housing |       1  | 
| water   |       1  | 
| food    |       1  | 
| housing |       2  | 
| rent    |       2  | 
| water   |       2  | 
| housing |       3  | 
+---------+----------+

注意users_needs表如何定义一个用户与一个或多个需求之间的关系(或者根本没有,如用户编号4所示。)

为了进一步规范化您的数据库,您还应该使用另一个名为needs的表,如下所示:

-- TABLE: needs

+---------+---------+
| need_id | name    |
+---------+---------+
|       1 | housing | 
|       2 | water   | 
|       3 | food    |   
|       4 | rent    | 
+---------+---------+

然后users_needs表应该引用needs表的candidate key而不是重复文本。

-- TABLE: users_needs (instead of the previous one)

+---------+----------+
| need_id | user_id  |
+---------+----------+
| 1       |       1  | 
| 2       |       1  | 
| 3       |       1  | 
| 1       |       2  | 
| 4       |       2  | 
| 2       |       2  | 
| 1       |       3  | 
+---------+----------+

您可能还有兴趣查看以下维基百科文章,以进一步阅读有关列内重复值的信息:


<强>更新

要完全回答您的问题,如果您遵循上述指南,那么对数据进行排序,计数和汇总应该是直截了当的。

要按需要对结果集进行排序,您可以执行以下操作:

SELECT     users.name, needs.name
FROM       users
INNER JOIN needs ON (needs.user_id = users.user_id)
ORDER BY   needs.name;

您还可以计算每个用户选择的需求数量,例如:

SELECT     users.name, COUNT(needs.need) as number_of_needs
FROM       users
LEFT JOIN  needs ON (needs.user_id = users.user_id)
GROUP BY   users.user_id, users.name
ORDER BY   number_of_needs;

答案 1 :(得分:0)

我对目标感到有点困惑。这是一个UI问题还是您只是在确定谁有多个需求时遇到了问题?

需求的数量是差异:

Len([Needs]) - Len(Replace([Needs],',','')) + 1

您能否提供有关您要完成的排序的更多信息?

<强>更新 我认为这些基于Oracle的帖子可能包含您所需的内容:postpost。唯一的区别是你最好使用我上面列出的方法找到逗号分隔的片段的数量,而不是做作者建议的翻译(...)。希望这有帮助 - 它是基于Oracle的,但我没有看到。