2015-12-26 7 views
0

在一个绝对错误代码只元的表格选择,我试图做这样的事情:从其中aa列包含从另一列

SELECT * FROM table2 WHERE 
table2.items CONTAINS ONLY ELEMENTS FROM table1.item 

这是一个有点混乱,但I'l尝试解释:

我已经一个表(表1),其具有与一个元件的列中的每一行中(让我们称之为A,B,C,d)

id - [item] 

1 - ["A"] 
2 - ["B"] 
3 - ["C"] 
4 - ["D"] 

然后,我有另一个表(表2)其列包含字符串像:

TABLE2 
row# - [items] 

row1 - ["A, B"] 
row2 - ["A, B, C"] 
row3 - ["A, B, C, E"] 

我要的是从包含存在于表1只元素,所以ROW1和ROW2,在这个例子表2只选择行。

是否可以在不改变表格结构的情况下做到这一点?否则,我需要做哪些改变?

--------- [编辑] -------------

所以我改变了我的结构,以便能够使用IN操作符和它的工作(几乎)很好! 虽然有新问题发生。 由于我的table2字符串有不同的长度,我新的table2有一些空的单元格。

--- [更新] ---

所以,如果我想检查是否

|item1|item2|item3|item4| row | 
| A | B | C |  | 2 | 

2行是table1.item(同上),这些条件我的一个要求是

WHERE NULL IN table1.item 

它不是!我需要的是只检查项目是否在其他表格中,当项目不是NULL时。我试着玩那个

+0

那么,有什么新的表2的结构?对于这个最小的例子,我想你只需要一个唯一的标识符(ID),一个非唯一值(A,B或C等)和一个group_id来关联相关的值。 – Redbeard011010

回答

2

是的,这是可能的。一个简单的方法是使用子查询。这将是这样的:

|ID | Value | Group_id| 
| 1 | A | 1  | 
| 2 | B | 1  | 
| 3 | C | 1  | 
| 4 | A | 2  | 
| 5 | B | 2  | 

这将是':

SELECT * FROM table1 WHERE some_value IN (SELECT some_value from table2); 

这将从如果你的表2是这样的表2中的列some_value

其中SOME_VALUE存在table1的恢复一切A,B,C'都在组1中,而组2中的'A,B'。现在,您可以非常容易地以不同的行检索与任何组关联的所有值。据我最初的问题可以知道,这个表不应该有任何NULL值(正如你在更新中提到的那样)

现在,要确定所有具有table1中存在的唯一元素的组,可能:

SELECT group_id FROM table2 WHERE group_id NOT IN (SELECT group_id FROM table2 WHERE value NOT IN (SELECT value from table1)); 

这产生一组包含在表1的所有值的结果,然后返回该组的外侧值的所有group_ids,然后否定这一点。有点复杂,有可能有更好的方法来做到这一点...

+0

这不需要我的table2为每个“item”分隔列,而不是仅包含所有项目的字符串? – KamenPurin

+0

它会的,是的。你需要研究的是所谓的标准化。我们希望在任何给定的“单元格”中只有单个值。因此,对于您的示例,您可能需要第三张表来保存每个值。例如:您不必让Table2.Row1同时拥有'A'和'B',您可以为该行分配一个Group_ID,创建一个名为Groups的第三个表,将两行插入Group_IDs(每个值为一行),并给这些行使用与Table2.Row1现在具有的值相同的Group_ID。这是将多个值与“父”记录相关联的常用方法 – Redbeard011010

+0

经过一些工作后,它几乎可以工作。介意看看OP的编辑部分? – KamenPurin

2

您的数据布局非常差。在SQL中,将行列表存储在行中是一个坏主意。原因如下:

  • 在关系数据模型中,每列应存储一个“事物”。
  • 关系数据库有很好的存储列表的方式。它被称为表格。
  • 数据库无法强制使用外键关系。

有时候,你会被其他人的糟糕设计决定所困住。 MySQL有一些可以提供帮助的功能。举例来说,如果“清单”只是逗号分隔的字符串:

SELECT t2.items 
FROM table2 t2 LEFT JOIN 
    table1 t1 
    ON find_in_set(t1.item, t2.items) > 0 
GROUP BY t2.items -- or this should really be an id column if available 
HAVING COUNT(*) = LENGTH(t2.items) - LENGTH(REPLACE(t2.ITEMS, ',', '')); 

你的列表格式有空格,所以你需要将其删除:

SELECT t2.items 
FROM table2 t2 LEFT JOIN 
    table1 t1 
    ON find_in_set(t1.item, replace(t2.items, ' ', '')) > 0 
GROUP BY t2.items -- or this should really be an id column if available 
HAVING COUNT(*) = LENGTH(t2.items) - LENGTH(REPLACE(t2.ITEMS, ',', ''));