2014-02-12 15 views
0

我希望有人能幫助我。我有兩個表:小部件表和評論表。在一對多查詢中使用SQL JOIN

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

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

我想解決一個CodeGo.net,應用程序的SQL查詢。這裏是場景:對於給定的製造商(widget.id),返回所有的widget.name,widget.color,widget.msrp和對於每個返回的小部件,返回相應小部件的評論(即評論)。評級,reviews.source,reviews.review)。一個小部件可能有一個,很多或沒有評論。

我使用菲爾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> 

我必須使用子查詢試圖解決方案,foreach循環和GROUP_CONCAT ;然而,類似問題的Stackoverflow的受訪者表示使用JOIN。

即使使用JOIN,我也找不到合適的解決方案。這裏是我的(略)最後一次嘗試,這是不正確的:

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

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

我相當有信心,我可以建立從表名和列名失蹤的評論和評論標籤。主要問題是缺少行。 Widget-1應該看起來像這樣每個數據庫:

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

我目前的查詢只返回符合條件的第一行。 (我將結果呈現爲XML的事實是無關緊要的,我認爲它可能比數組更容易閱讀)。先謝謝您!


編輯


鑑於outis和GROUP BY VAD軟的解釋,我有一個問題的更好地處理。當我刪除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> 

不幸的是,生成的XML必須符合特定的DTD,這需要涉及到特定圖標所有評論將被包含在一個父標籤內。你是否指出這是不可能的;還是有另一種方法來實現這一點;或(可能)我錯過了一個關鍵點? -再次感謝。

+0

在您的SQL查詢你有'WHERE wine.id = 46',但沒有別名或表稱爲'wine',所以我不希望這種查詢到實際工作。 –

+1

最後還有'GROUP BY'也會導致它失敗。無論如何,它在你的查詢中並不需要。 –

+0

適當的[示例代碼](http://sscce.org/)(這裏是SQL語句)比任何ad hoc模式和示例數據格式更有用。請爲[samples]使用CREATE TABLE和INSERT ... VALUES(http://weblogs.sqlteam.com/jeffs/archive/2008/05/13/question-needed-not-answer.aspx)。對於期望的結果,XML很好,但也要考慮SQL結果。 – outis

回答

1

在您的scenerio中,GROUP BY並不意味着因爲您想要特定的id的細節,並且基於您將獲得參考表的詳細信息,而不使用GROUP BY子句使用相同的查詢,因此它會查找所有在子表中也記錄相同的ID。所以它會重複主表數據爲widget.name,widget.color,widget.msrp,但不要在這裏放置widget.id。希望這可以幫助。

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

感謝

+0

謝謝Vad Soft。你闡明瞭我原來的問題。如果將GROUP BY多行合併爲一個,是否可以將結果作爲一個父小部件標記的子項返回爲''和''? – user2514625