使用逗号作为分隔符在MySQL中解析

时间:2012-11-05 03:39:09

标签: mysql

我有两张桌子

表1,以逗号分隔的用户列表

Name    UserID
abc     A,B,C,D
def     A,B,C

表2

Name   UserID
abc    A
abc    B
abc    C
def    A
def    B

我需要找到table1中每个Name但不在table2中的用户(当tableID2中存在UserID to Name对但在table1中不存在CSV时,将不会有实例)。

输出应为

Name    UserID
abc     D
def     C

我可以用PHP做到这一点但有没有办法可以通过查询来完成? 我不知道从哪里开始以防我这样做作为查询。我可以使用逗号分隔MySQL吗?

2 个答案:

答案 0 :(得分:3)

我将测试数据插入SQLFiddle中的测试模式,并运行后面的查询。

以下是带有测试和积极结果的SQLFiddle链接: http://sqlfiddle.com/#!2/83dfd/4/0

以下是查询:

SELECT
COALESCE(NORMALIZED_TABLE1.NAME, TABLE2.NAME) AS NAME,
COALESCE(NORMALIZED_TABLE1.USERID, TABLE2.USERID) AS USERID
FROM (
     SELECT NAME,
     SUBSTRING(
          USERID
          FROM CASE
               WHEN INDEX_TABLE.POS = 1 THEN 1
               ELSE INDEX_TABLE.POS + 1
               END
          FOR CASE LOCATE(',', USERID, INDEX_TABLE.POS + 1)
              WHEN 0 THEN CHARACTER_LENGTH(USERID) + 1
              ELSE LOCATE(',', USERID, INDEX_TABLE.POS + 1)
              END
              - CASE
                WHEN INDEX_TABLE.POS = 1 THEN 1
                ELSE INDEX_TABLE.POS + 1
                END
     ) AS USERID
     FROM TABLE1
     INNER JOIN (
          SELECT @rownum:=@rownum+1 POS
          FROM (
             SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3
             UNION SELECT 4 UNION SELECT 5 UNION SELECT 6
             UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
          ) a, (
             SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3
             UNION SELECT 4 UNION SELECT 5 UNION SELECT 6
             UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
          ) b, (
             SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3
             UNION SELECT 4 UNION SELECT 5 UNION SELECT 6
             UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
          ) c, (SELECT @rownum:=0) r
     ) INDEX_TABLE
     ON INDEX_TABLE.POS <= CHAR_LENGTH(TABLE1.USERID)
     AND (
          INDEX_TABLE.POS = 1
          OR SUBSTRING(USERID FROM INDEX_TABLE.POS FOR 1) = ','
     )
) AS NORMALIZED_TABLE1
LEFT OUTER JOIN TABLE2
ON NORMALIZED_TABLE1.NAME = TABLE2.NAME
AND NORMALIZED_TABLE1.USERID = TABLE2.USERID
WHERE TABLE2.NAME IS NULL;

如果table1中的列宽很长,则可能需要展开“INDEX_TABLE”子查询。您可以使用此链接上的代码复制并粘贴它,以执行此操作:
http://www.experts-exchange.com/Database/MySQL/A_3573-A-MySQL-Tidbit-Quick-Numbers-Table-Generation.html

答案 1 :(得分:0)

如果表是固定的(您希望处理这些表),那么设计一个类来从它们读取数据,而不是直接从这些预定义的表中保存集合数据;让您的对象在您的应用程序域中实时处理读取数据,以获得完整的可访问性。 :-D