2017-03-04 96 views
1

我已經構建了以下查詢:複雜的SQL查詢沒有給預期的結果

SELECT p.id person_id, p.name person_name, p.dob person_dob, 
     a.attribute, pa.value, t.type person_type 

     FROM  people    p 
     LEFT JOIN person_attributes pa  ON pa.person_id=p.id 
     LEFT JOIN person_types   pt  ON pt.person_id=p.id 
     LEFT JOIN attributes   a  ON pa.attribute_id=a.id 
     LEFT JOIN types    t  ON pt.type_id=t.id 
     WHERE p.id='$person_id' 

這裏是我的數據庫結構:

people(id,name,dob) 
person_attributes(id,person_id,attribute_id,value) 
attributes(id,attribute) 
person_types(id,person_id,type) 
types(id,type) 

查詢是不是給了我預期的結果,因爲它的結果返回一些對象而不是一個。我想選擇人員和所有相關數據(屬性和類型)。我想我已經搞亂了那些JOINS或其他東西。我試着重新安排他們等

目前的結果是:

Array 
(
[0] => stdClass Object 
    (
     [person_id] => 2 
     [person_name] => Marta Smith 
     [person_dob] => 1995-03-16 
     [attribute] => size 
     [value] => the_value 
     [person_type] => type2 
    ) 

[1] => stdClass Object 
    (
     [person_id] => 2 
     [person_name] => Marta Smith 
     [person_dob] => 1995-03-16 
     [attribute] => size 
     [value] => the_value 
     [person_type] => type1 
    ) 

[2] => stdClass Object 
    (
     [person_id] => 2 
     [person_name] => Marta Smith 
     [person_dob] => 1995-03-16 
     [attribute] => weight 
     [value] => the_value 
     [person_type] => type2 
    ) 

[3] => stdClass Object 
    (
     [person_id] => 2 
     [person_name] => Marta Smith 
     [person_dob] => 1995-03-16 
     [attribute] => weight 
     [value] => the_value 
     [person_type] => type1 
    ) 

) 

預期結果:

[0] => stdClass Object 
    (
     [person_id] => 2 
     [person_name] => Marta Smith 
     [person_dob] => 1995-03-16 
     [attributes] => // array of all attributes with values here 
     [types] => // array of all person types here 
    ) 

是否有可以對查詢進行格式化它如預期的任何變化?或者唯一的方法就是使用PHP,循環遍歷結果並創建新的對象?

+1

我覺得你可以'組by'的'p.id'然後'group_concat'的'a.attribute'和't.type'。這將創建一個分隔符字符串,而不是'attributes'和'types'索引的數組。你可以爆炸它來獲得一個數組,但是你選擇的任何分隔符(確保它是唯一的)。 – chris85

+0

@ chris85感謝您的提示。我會嘗試。 –

+1

這是一個簡單的查詢,返回一個簡單實用的結果。不需要修改。 – Strawberry

回答

0

嗯,我想問題是在你的SELECT字段部分。它應該是:

SELECT p.id AS person_id, p.name AS person_name, p.dob AS person_dob, 
    a.attribute, pa.value, t.type AS person_type 
0

這就是SQL是如何工作的 - 您遇到的問題是,SQL是要回報你的,你在想什麼,作爲一個嵌套的樹形結構二維扁平的表結構。換句話說,你的SQL結果是這樣的:

2 Marta Smith 1995-03-16 size the_value type1 
2 Marta Smith 1995-03-16 weight the_value type1 
2 Marta Smith 1995-03-16 weight the_value type2 

而你需要想出一種方法來聚合/分組信息。您有幾種選擇:

  1. 向上突破查詢到多個查詢得到的只有從SQL您有興趣在不同的組這通常是不可取的 - 它會增加更多的往返行程服務器和仍然要求您在php或javascript中執行一些客戶端聚合操作。
  2. 在PHP或JavaScript中聚合/分組事物 - 最好分解爲可重用的業務邏輯層。該層將遍歷SQL結果並將其轉化爲您的預期結果。
  3. 在XSLT中使用MySQL中的某種XML功能進行轉換(XML output from MySQL)。這對於MySQL來說並不是一個好的選擇,但是對於RDBMS來說更好的選擇可以更充分地支持XML或JSON輸出格式(如SQL Server,Oracle或DB2)。
  4. 把你的一些連接變成子查詢並連接它們,然後使用字符串分割功能 - 但要小心這個,以防你的數據意外地包含你的分隔符(我不是這種方法的忠實粉絲)。一個例子見Concatenate many rows into a single text string? - 基本上採取任何的0/1多的關係,並使用子查詢,而不是LEFT JOIN