MySQL查询列如列

时间:2011-01-12 18:44:03

标签: php mysql sql

我正在开展一个小项目,涉及抓取为每个组存储的联系人列表。本质上,数据库的设置使得每个组都有一个主要和次要联系人,不出所料地存储为Group.Primary和Group.Secondary。目标是为每个组拉出每个主要和次要联系人,并将其显示在可排序的表格中。

我已经完成了可排序表,但我遇到了一个小问题。每个主要和次要字段可以有多个以逗号分隔的联系人。例如,如果Primary包含123,256,则需要使用ID为123和256的两个联系人。我原本打算使用如下格式的查询:

SELECT * 
  FROM Group G, 
       Contacts C 
 WHERE G.Primary LIKE %C.ID% 
    OR G.Secondary LIKE %C.ID%

所以我可以跳过逗号部分,但我似乎无法找到一个有用的查询。

我的问题是,我只是在这里忽略了什么?是否有一个简单的查询可以让我这样做?或者我最好分别获取组和联系人,然后将两者结合起来。我认为前者在阅读时更容易理解,这是一个加号,因为这是一个共享项目,但如果不可能,我会做后者。

这段代码已经过简化,但它得到了重点。

3 个答案:

答案 0 :(得分:3)

如果我理解正确,您想使用MySQL FIND_IN_SET function

SELECT * 
  FROM Group G 
  JOIN Contacts C ON FIND_IN_SET(c.id, g.primary)
                  OR FIND_IN_SET(c.id, g.secondary)

但我强烈建议你规范化表格 - 如果可能的话,不要存储逗号分隔的列表。

答案 1 :(得分:0)

我认为你最好将这两个数据值分成不同的表,然后使用JOIN来进行链接。比方说,如果你将你的id字段转换为字符串,那么你可以使用LIKE比较,你最终会得到一堆垃圾比赛。例如,如果您的主要ID是1,而您的辅助ID是35,那么您将匹配以下内容(此列表并非详尽无遗):

1: 1, 2: 35
1: 35, 2: 1
1: 10, 2: 135
1: 431, 2: 3541

我要做的是这样的事情:

SELECT * 
FROM Group G
LEFT JOIN Contacts c1 on g.primary = c1.id
LEFT JOIN Contacts c2 on g.secondary = c2.id
WHERE
c1.id IS NOT NULL
OR
c2.id IS NOT NULL

如果我能正确理解这个问题,我认为这样可以为您提供您真正想要的数据。

答案 2 :(得分:0)

撒旦一直在你的数据库中,对它进行反规范化,让你陷入复杂而缓慢的查询生活。

您是否有能力改变数据库的结构?如果它正在生产中,我假设没有。如果做不到这一点,您可能需要考虑在运行此报告之前立即创建主要和次要联系人的规范化表格。

如果你不能这样做,你需要制定一个永远有效的字符串匹配算法。您提出的问题是您需要考虑联系人ID为23(或甚至3),这将匹配23,123,223,231等。要做到这一点,你需要在你要比较的两个字符串的开头和结尾添加逗号,然后执行LIKE。

糟糕。或者您可以使用上面Ponies描述的I-never-know FIND_IN_SET函数。