简体   繁体   English

在一对多查询中使用SQL JOIN

[英]Using SQL JOIN in One-to-Many Query

I am hoping someone can help me. 我希望有人能帮助我。 I have two tables: widget table and reviews table. 我有两个表:小部件表和评论表。

widget
-------------------
widget_id   PK
id  (foreign key)
name
color
msrp

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

I am trying to work out a sql query for a Codeigniter app. 我正在尝试为Codeigniter应用程序执行sql查询。 Here's the scenario: For a given manufacturer (widget.id), return all widget.name, widget.color, widget.msrp AND for each of these returned widgets, return the review(s) of the respective widgets (ie, reviews.rating, reviews.source, reviews.review). 这是一种情况:对于给定的制造商(widget.id),返回所有的widget.name,widget.color,widget.msrp,并为每个返回的窗口小部件返回相应窗口小部件的评论(即评论)。评级,reviews.source,reviews.review)。 One widget may have one, many or no reviews. 一个小部件可能只有一个,很多或没有评论。

I'm using Phil Stugeon's REST library, which returns the query as XML, so the returned data construct might look similar to this: 我正在使用Phil Stugeon的REST库,该库以XML形式返回查询,因此返回的数据构造可能类似于以下内容:

<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>

I have tried solutions using subqueries, foreach loops, and GROUP_CONCAT; 我已经尝试过使用子查询,foreach循环和GROUP_CONCAT的解决方案; however, respondents on Stackoverflow for similar questions suggest the use of a JOIN. 但是,对于Stackoverflow的类似问题,受访者建议使用JOIN。

I cannot find the right solution even with a JOIN. 即使使用JOIN,我也找不到正确的解决方案。 Here is my (abbreviated) last attempt, which is incorrect: 这是我(略)最后一次尝试,这是不正确的:

$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");

Returned XML: 返回的XML:

<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>

I am fairly confident I can build the missing reviews and review tags from the table name and column name. 我非常有信心,我可以根据表名和列名构建缺少的评论和评论标签。 The major issue is missing rows. 主要问题是缺少行。 Widget-1 should look like this per the database: 每个数据库的Widget-1应该如下所示:

<root>
   <widget>
      <name>widget-1</name>
      <color>red</color>
      <reviews>
         <review>
            <rating>92</rating>
            ...
         <review>
         <review>
            <rating>99</rating>
            ...
         <review>
      </reviews>
    </widget>
  …

My current query only returns the first row that meets the conditions. 我当前的查询仅返回符合条件的第一行。 (The fact that I've presented the result as XML is inconsequential. I thought it may be easier to read than arrays.) Thank you in advance! (我将结果表示为XML的事实是无关紧要的。我认为它可能比数组更容易阅读。)预先谢谢您!


EDIT 编辑


Given outis and vad soft's explanation of GROUP BY I have a better handle of the problem. 鉴于outis和vad soft对GROUP BY的解释,我可以更好地解决该问题。 When I remove GROUP BY and run the query, the following returns: 当我删除GROUP BY并运行查询时,将返回以下内容:

<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>

Unfortunately, the resultant XML needs to conform to a particular DTD, which requires all reviews pertaining to a particular widget to be contained within a single parent tag. 不幸的是,生成的XML需要符合特定的DTD,这要求与特定小部件有关的所有评论都包含在单个父标记中。 Are you indicating that this will not be possible; 您是否表示不可能? or is there another way to achieve this; 还是有另一种方式来实现这一目标; or (and likely) have I missed a critical point? 还是(很可能)我错过了关键点? -Thanks again. -再次感谢。

In your scenerio, the GROUP BY doesn't mean because you want particular id's details and based on you will get the details of your reference table, instead use the same query without using GROUP BY clause hence it will find all the records for the same id in child table also. 在您的Scenerio中,GROUP BY并不意味着因为您想要特定ID的详细信息,并且基于此您将获得引用表的详细信息,而是使用相同的查询而不使用GROUP BY子句,因此它将查找相同记录的所有记录子表中的ID。 So it will repeat the master table data as widget.name, widget.color, widget.msrp but don't put here widget.id. 因此它将重复主表数据为widget.name,widget.color,widget.msrp,但不要在此处放置widget.id。 Hope this helps. 希望这可以帮助。

$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");

Thanks 谢谢

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM