【问题标题】:Select from one table matching criteria in another?从一个表中选择另一个匹配条件?
【发布时间】:2011-03-27 02:15:10
【问题描述】:

非常感谢有关跨表的 SQL 查询的帮助。我意识到这种事情经常被问到,但我找不到足够相似的问题来理解答案。

我想从table_A 中选择在table_B 中有相应标记的行。
因此,例如,“从table_a 中选择标记为‘椅子’的行”将返回table_C

另外,idtable_a 中是唯一的,而不是在table_b 中。

table_A:             table_B:                  table_C:

id    object         id    tag                 id    object
1     lamp           1     furniture           3     stool
2     table          2     furniture           4     bench
3     stool          3     furniture
4     bench          4     furniture
                     4     chair
                     3     chair

或者,有没有更好的方法来组织数据?

【问题讨论】:

    标签: sql multiple-tables


    【解决方案1】:

    最简单的解决方案是相关子选择

    select
        A.*
    from
        table_A A
    where
        A.id in (
            select B.id from table_B B where B.tag = 'chair'
    )
    

    或者,您可以加入表并过滤您想要的行:

    select
        A.*
    from
        table_A A
    inner join table_B B
        on A.id = B.id
    where
        B.tag = 'chair'
    

    您应该对两者进行分析,看看哪个在您的数据集上更快。

    【讨论】:

    • @rjschnorenberg 的建议更好,如果您有机会更改架构。在这种情况下,您将使用两个 INNER JOIN 子句连接三个表 ItemsItem_TagsTags。
    • 太好了,这很有帮助。我不知道您可以像这样过滤联接表中的列。
    • 其实你也可以将连接行写成“inner join table_B B on A.ID = B.ID AND B.tag = 'chair'”,但我更喜欢将过滤器放在WHERE下。跨度>
    • 以下哪一项是“更好”的实践和表现?还是完全偏爱?
    【解决方案2】:

    您应该使用链接表使标签成为自己的表。

    items:
    id    object
    1     lamp  
    2     table   
    3     stool  
    4     bench 
    
    tags:
    id     tag
    1      furniture
    2      chair
    
    items_tags:
    item_id tag_id
    1       1
    2       1
    3       1
    4       1
    3       2
    4       2
    

    【讨论】:

    • 假设您可以控制架构,这是更好的答案。如果您不这样做,请考虑创建一个合并两个对象表的视图,以便您可以按照此答案的建议进行操作。
    【解决方案3】:
    select a.id, a.object
    from table_A a
    inner join table_B b on a.id=b.id
    where b.tag = 'chair';
    

    【讨论】:

      【解决方案4】:

      我也有类似的问题(至少我认为是类似的)。在这里的一个回复中,解决方案如下:

      select
          A.*
      from
          table_A A
      inner join table_B B
          on A.id = B.id
      where
          B.tag = 'chair'
      

      我想成为的那个 WHERE 子句:

      WHERE B.tag = A.<col_name>
      

      或者,在我的具体情况下:

      WHERE B.val BETWEEN A.val1 AND A.val2
      

      更详细:

      表 A 包含一组设备的状态信息。每个状态记录都带有该状态的开始和停止时间。表 B 包含定期记录的带时间戳的设备数据,我想在表 A 所示的期间内提取这些数据。

      【讨论】:

        猜你喜欢
        • 2020-03-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-28
        • 2014-10-25
        • 1970-01-01
        • 2021-05-13
        相关资源
        最近更新 更多