在mySQL中嵌套子查询中选择多个列的推荐方法

时间:2015-02-08 17:41:57

标签: mysql select subquery

建议在嵌套子查询中选择多个列使用哪些方法?我已经有一段时间了,因为我已经对任何疑问进行了编码,而且我很难解决这个问题。具体挑战在下面的代码的第2行。 IN操作数在此处不起作用(请参阅下面的错误消息),我不确定它是否仅仅是语法I&的问题#39; m使用,和/或有一个更好的方法来解决这个问题(即使用HAVING操作数或JOIN语句)

SELECT * FROM Rules WHERE Rules.LNRule_id 
    IN(SELECT LNRule_id1,LNRule_id2,LNRule_id3,LNRule_id4 FROM Silhouette
    WHERE Silhouette.Silhouette_Skirt=(SELECT Silhouette_Skirt FROM Style
        WHERE Style.Style_Skirt='$Style_Skirt')
    )

此查询的目的是SELECTRules中表Style(即$Style_Skirt)中特定值的所有相关行,它通过将它与几个因素中的一个相匹配 - 在这种情况下是服装的Silhouette。因此,我在查询的这一部分中尝试做的是SELECTRules中的所有行,其ID(LNRule_id)与任何指定列中的值匹配表Silhouette

(SELECT LNRule_id1,LNRule_id2,LNRule_id3,LNRule_id4 FROM Silhouette WHERE Silhouette.Silhouette_Skirt=(...)) 

修改 存在多对多关系(每个Silhouette有几个适用的规则,每个规则可以应用于多个剪影)。所有规则都存在于表格规则中。 (每行一个),每个规则都有一个ID(' LNRule_id' )。表' Silhouette'有列,告诉它需要从'规则'中调用哪些行。通过' LNRule_id' (LNRule_id1,2,3,4表示应调用哪些规则,并在表格中存储相关行的ID的值'规则')


IN操作数当前生成的错误消息为:

  

SQLSTATE [21000]:基数违规:1241操作数应包含1   列(S)

2 个答案:

答案 0 :(得分:1)

mysql抱怨在IN的一侧有一个列,而在另一侧你有一个多列的行集。为了使IN运算符起作用,IN右侧的行集必须具有与左侧完全相同的列数;在这种情况下,一栏。

如果你做了类似WHERE LNRule_id IN( SELECT LNRule_Id1 ...) OR LNRule_id IN( SELECT LNRule_Id2 ...) OR ... OR ...之类的事情,你可能会想要实现的目标,但最终的查询将是一个怪物,它的表现将是可怕的。可能还有其他方法可以解决这个问题,但是你尝试的任何事情都可能同样是残暴的。

我没有足够的信息来确定我所说的内容,但在我看来,您遇到此问题的原因是您的数据库架构未规范化。通常,只要您看到一个包含一组列的表,这些列的名称都以相同的前缀开头并以数字结尾,这意味着某个人在某个地方没有规范化他们的数据。

为了解决问题中的编辑问题,您实施的内容在概念上可能是多对多关系,但就关系数据库而言,(您知道,科学,理论,既定实践,必要方法)让事情真正发挥作用,) 绝对不是 多对多的关系。使用column1,column2,column3,... columnN实现了多对多关系 not 。为了确保我没有做到这一点,你可以在这里阅读其他人对多对多关系的看法:

Many-to-many relations in RDBMS databases

所以,我的建议,如果我正确理解发生了什么,将会引入一个名为SilhouetteRules的新表,它包含两列,silhouette_id和rule_id。此表将实现轮廓和规则之间的多对多关系。当然,你摆脱了Silhouette的所有rule1,rule2,rule3等列。

完成后,您可以使用如下查询获取所有轮廓和与之关联的所有规则:

SELECT * FROM Silhouette 
    LEFT JOIN SilhouetteRules ON 
        Silhouette.id = SilhouetteRules.silhouette_id 
    LEFT JOIN Rules ON 
        SilhouetteRules.rule_id = Rules.id 

上述查询将为每个轮廓生成多行,其中轮廓字段在行与行之间将相同,并且只有规则字段会有所不同。不要对此感到惊讶,这是关系数据库的工作方式。

给定given_silhouette_id,您可以使用如下查询检索与其关联的所有规则:

SELECT * FROM Rules
    LEFT JOIN SilhouetteRules ON 
         Rules.id = SilhouetteRules.rule_id 
WHERE 
    SilhouetteRules.silhouette_id = given_silhouette_id

因此,您将在查询中使用此查询作为子查询,例如问题中的查询。

现在,关于问题中的查询,我无法准确地告诉您如何修改它以使其与我提出的规范化一起工作,因为我无法理解它。您会看到,即使您使用SELECT * FROM table WHERE single-column IN multi-column-rowset修复了当前的问题,还会出现另一个问题:WHERE Silhouette.Silhouette_Skirt=(SELECT ...部分也无法正常工作,因为您无法将列的值与选择语句的结果。所以,我不知道你在那里做什么。希望,一旦规范化架构并修复查询的第一个问题,第二个问题的解决方案就会变得很明显,或者你可以在stackoverflow上提出另一个问题。

P.S。 Mihai的回答是否有效?

答案 1 :(得分:1)

我想你想要这个查询

SELECT * FROM  Rules r
JOIN Silhouette s
(ON r.LNRule_id=s.LNRule_id1
OR r.LNRule_id=s.LNRule_id2
OR r.LNRule_id=s.LNRule_id3
OR r.LNRule_id=s.LNRule_id4)
JOIN Style st
ON s.Silhouette_Skirt=st.Silhouette_Skirt
WHERE st.Silhouette_Skirt = '$Style_Skirt'