2015-06-19 54 views
0

我有一個不尋常的SQL問題,我不太清楚如何最好地解釋,所以請耐心等待。我有三張桌子,一個是志願者組織,一個是用戶,另一個是用戶的詳細信息。硬SQL查詢

#Table 1# 
## Name President Secretary Treasurer 
---------- 
ABC 571 123 456 
DEF 457 582 444 

#Table 2# 
## Id Name 
---------- 
571 Joe Blogs 
123 Joanne Blogs 

#Table 3# 
## Id Address City 
---------- 
571 123...... Somewhere 
123 456..... Somewhere Else 

我所試圖做的是允許用戶在組織名稱的順序組裝PDF地址標籤,所以他們可能會說,他們希望從每一個組織的總統或總統和祕書所以它會讀取所有組織的總裁和祕書ID,並將他們加入到地址細節中,並按組織的順序進行組裝。他們可能會選擇只做總統或總統和祕書或上述任何組合。它必須按照組織順序進行排序並按此順序返回用戶對象。

例如

ABC -> President 
ABC -> Secretary 
DEF -> President 
DEF -> Secretary 

我已經嘗試了幾種選擇。首先是,

$query = $db->getQuery(true); 
     $query->select($db->quoteName('a.name')); 
     $query->select($db->quoteName($this->show_exec)); 
     $query->from($db->quoteName('#__agshows_shows', 'a')); 
     $tableACount = 'b'; 
     $tableBCount = 'aa'; 
     foreach($this->show_exec as $column){ 
      $query->select($db->quoteName(array($tableACount . '.user_id', $tableACount . '.address_1', $tableACount . '.address_2', $tableACount . '.city', $tableACount . '.region', $tableACount . '.postal_code', $tableBCount . '.name'))) 
      ->join('LEFT', $db->quoteName('#__agshows_user_profile', $tableACount) . ' ON (' . $db->quoteName($tableACount . '.user_id') . ' = ' . $db->quoteName($column) . ')') 
      ->join('LEFT', $db->quoteName('#__users', $tableBCount) . ' ON (' . $db->quoteName($tableBCount . '.id') . ' = ' . $db->quoteName($column) . ')'); 

      $tableACount ++; 
      $tableBCount ++; 
     } 

     switch($this->show_sort) { 

      case 'a.title': 
       $query->order($db->quoteName('a.title') . ' ASC'); 
      break; 

      case 'a.groupid': 
       $query->order($db->quoteName('a.groupid') . ' ASC'); 
      break; 

      default: 
       $query->order($db->quoteName('a.title') . ' ASC');    
     } 

     $db->setQuery($query); 
     $show_users = $db->loadObjectList(); 

這個問題是因爲它通過foreach循環覆蓋每個組織的其他對象。我希望它是靈活的($ this-> show_exec包含一列可供選擇的列,即a.president,a.secretary)。

第二個方案是,

if(!empty($this->show_exec)) { 
     // Get the Show Exec user IDs. 
     $query = $db->getQuery(true); 
     $query->select($db->quoteName($this->show_exec)); 
     $query->from($db->quoteName('#__agshows_shows')); 
     $db->setQuery($query); 
     $show_users = $db->loadAssocList(); 


     foreach ($show_users as $shows) { 
      foreach ($shows as $key=>$value) { 
       if($value != 0) { 
        $user_ids[]=$value; 

       } 
      } 
     } 
    } 

$query = $db->getQuery(true); 
    $query->select('a.*'); 
    $query->from($db->quoteName('#__agshows_user_profile') . ' AS a'); 

    // Join over the users names. 
    $query->select('uc.name') 
    ->join('LEFT', '#__users AS uc ON uc.id=a.user_id'); 

    $query->where('a.user_id IN ('. implode(',', $user_ids) . ')'); 

    $query->order($db->escape('a.city asc')); 

    $db->setQuery($query); 
    $recipients = $db->loadObjectList(); 

與這一個問題是,$ users_id是正確的順序,但是當它查詢第二表它沒有提到排序,只是返回的第二個表的順序不是我想要的順序....

是否有一個乾淨的方法可以在一箇中完成它?

或者有沒有辦法我可以排序第二個查詢以$ user_ids數組的順序返回結果?

我希望是有道理的..

感謝

回答

0

我想下面的查詢可能爲你工作:

SELECT 
    * 
FROM 
    (SELECT 
    o.name AS org_name, 
    u1.name AS username, 
    'president' AS `type` 
    FROM 
    org o 
    LEFT JOIN users u1 
     ON u1.`id` = o.`president` 
    UNION 
    ALL 
    SELECT 
    o.name AS org_name, 
    u1.name AS username, 
    'secretary' AS `type` 
    FROM 
    org o 
    LEFT JOIN users u1 
     ON u1.`id` = o.`secretary` 
    UNION 
    ALL 
    SELECT 
    o.name AS org_name, 
    u1.name AS username, 
    'treasurer' AS `type` 
    FROM 
    org o 
    LEFT JOIN users u1 
     ON u1.`id` = o.`treasurer`) AS a 
ORDER BY a.org_name ; 

我假設用戶表的主鍵,將用作外鍵在總統,祕書&組織表中的司庫。

以下查詢的輸出將生成一個虛擬列「type」,您可以在代碼中使用它來確定組織中特定用戶的角色。您還需要動態創建此查詢,以便只需要總裁或祕書或司庫或他們的任何組合時,處理這種情況。

+0

完美的作品! –

+0

現在我只需要讓它在Joomla中工作,如果您知道,這是我的問題。 http://joomla.stackexchange.com/questions/10503/joomla-3-3-6-union-sql-issue –

+0

對不起,我不知道Joomla :( –