首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在一对多查询中使用SQL联接

在一对多查询中使用SQL联接
EN

Stack Overflow用户
提问于 2014-02-12 05:36:56
回答 1查看 184关注 0票数 0

我希望有人能帮我。我有两个表:小部件表和审查表。

代码语言:javascript
运行
复制
widget
-------------------
widget_id   PK
id  (foreign key)
name
color
msrp

reviews
------------
review_id PK
widget_id (foreign key)
rating
source
review

我正试图为Codeigniter应用程序编写一个sql查询。下面是场景:对于给定的制造商(widget.id),返回所有widget.name、widget.color、widget.msrp以及每个返回的小部件,返回相应小部件的评审(即reviews.rating、reviews.source、reviews.review)。一个小部件可能有一个、多个或没有评论。

我正在使用菲尔·斯图金的REST库,它以XML的形式返回查询,因此返回的数据结构可能类似于以下内容:

代码语言:javascript
运行
复制
<root>
   <widget>
           <name>widget-1</name>
            <color>blue</color>
            <msrp>75.50</msrp>
            <reviews>
               <review>
                 <rating>95</rating>
                 <source>some reviewer 1</source>
                 <review>great widget!</review>
               </review>
               <review>
                 <rating>65</rating>
                 <source>some reviewer 2</source>
                 <review>Poor widget.</review>
               </review>
            <reviews>
    </widget>
    <widget>
           <name>widget-2</name>
           <color>red</color>
           <msrp>25.50</msrp>
    </widget>
 </root>

我尝试过使用子查询、foreach循环和GROUP_CONCAT的解决方案;但是,对于类似的问题,Stackoverflow上的应答者建议使用JOIN。

即使加入,我也找不到正确的解决办法。这是我最后一次尝试(缩写),这是不正确的:

代码语言:javascript
运行
复制
$widget = $this->db->query("SELECT
    widget.name
    , widget.color
    , reviews.rating AS rating
FROM
    widget
LEFT JOIN reviews
ON (widget.widget_id = reviews.widget_id)
WHERE widget.id = 46
GROUP BY widget.widget_id");

返回的XML:

代码语言:javascript
运行
复制
<root>
   <widget>
      <name>widget-1</name>
      <color>red</color>
      <rating>92</rating>
   </widget>
   <widget>
      <name>widget-2</name>
      <color>green</color>
      <rating>86</rating>
   </widget>
   <widget>
      <name>widget-3</name>
      <color>blue</color>
   </widget>
</root>

我很有信心可以从表名和列名构建缺少的评论和检查标记。主要问题是缺少行。小部件-1应该如下所示:

代码语言:javascript
运行
复制
<root>
   <widget>
      <name>widget-1</name>
      <color>red</color>
      <reviews>
         <review>
            <rating>92</rating>
            ...
         <review>
         <review>
            <rating>99</rating>
            ...
         <review>
      </reviews>
    </widget>
  …

我的当前查询只返回满足条件的第一行。(我已经将结果显示为XML,这是无关紧要的。我认为它可能比数组更容易阅读。)提前谢谢你!

编辑

考虑到outis和vad对GROUP BY的解释,我对这个问题有了更好的处理。当我移除GROUP BY并运行查询时,以下内容将返回:

代码语言:javascript
运行
复制
<root>
   <widget>
      <name>widget-1</name>
      <color>red</color>
      <rating>92</rating>
   </widget>
   <widget>
      <name>widget-1</name>
      <color>red</color>
      <rating>99</rating>
   </widget>
   <widget>
      <name>widget-2</name>
      <color>green</color>
      <rating>86</rating>
   </widget>
   <widget>
      <name>widget-3</name>
      <color>blue</color>
   </widget>
</root>

不幸的是,生成的XML需要符合特定的DTD,而DTD要求与特定小部件相关的所有评审都包含在一个父标记中。您是否表示这是不可能的;还是有其他方法来实现这一点;或者(很可能)我又错过了一个临界点?-Thanks。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-02-12 06:04:43

在您的场景中,组并不意味着因为您想要特定id的详细信息,并且基于您将获得引用表的详细信息,而是使用相同的查询而不使用GROUP子句,因此它也将在子表中找到相同id的所有记录。因此,它将以widget.name、widget.color、widget.msrp的形式重复主表数据,但不要在这里放置widget.id。希望这能有所帮助。

代码语言:javascript
运行
复制
$widget = $this->db->query("SELECT
    widget.name
    , widget.color
    , reviews.rating AS rating
FROM
    widget
LEFT JOIN reviews
ON (widget.widget_id = reviews.widget_id)
WHERE widget.id = 46");

谢谢

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21719537

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档