2015-09-12 67 views
5

我嘗試幾天瞭解如何將SQL查詢轉換爲laravel中的查詢生成器樣式。將SQL查詢轉換爲查詢生成器樣式

我的SQL查詢:

$tagid = Db::select("SELECT `id` FROM `wouter_blog_tags` WHERE `slug` = '".$this->param('slug')."'"); 

$blog = Db::select("SELECT * 
      FROM `wouter_blog_posts` 
      WHERE `published` IS NOT NULL 
      AND `published` = '1' 
      AND `published_at` IS NOT NULL 
      AND `published_at` < NOW() 
      AND (

      SELECT count(*) 
      FROM `wouter_blog_tags` 
      INNER JOIN `wouter_blog_posts_tags` ON `wouter_blog_tags`.`id` = `wouter_blog_posts_tags`.`tags_id` 
      WHERE `wouter_blog_posts_tags`.`post_id` = `wouter_blog_posts`.`id` 
      AND `id` 
      IN (
      '".$tagid[0]->id."' 
      )) >=1 
      ORDER BY `published_at` DESC 
      LIMIT 10 
      OFFSET 0"); 

哪裏我現在落得轉換爲查詢生成器:

$test = Db::table('wouter_blog_posts') 
->where('published', '=', 1) 
->where('published', '=', 'IS NOT NULL') 
->where('published_at', '=', 'IS NOT NULL') 
->where('published_at', '<', 'NOW()') 
    ->select(Db::raw('count(*) wouter_blog_tags')) 
->join('wouter_blog_posts_tags', function($join) 
{ 
$join->on('wouter_blog_tags.id', '=', 'wouter_blog_posts_tags.tags_id') 
->on('wouter_blog_posts_tags.post_id', '=', 'wouter_blog_posts.id') 
->whereIn('id', $tagid[0]->id); 
}) 
->get(); 

我已閱讀,我不能在其中一個連接使用。錯誤我現在得到:

調用未定義的方法照亮\數據庫\查詢\ JoinClause ::其中()

我真的不知道我怎麼能轉換我的SQL查詢生成器。我希望當我看到我的查詢有一個很好的工作轉換時,我可以理解我下次如何做。

+0

我沒有試過,但也許使用'> whereRaw([$標籤識別[0] - > id])'。只要確保最後的綁定參數是一個數組。然而,我不知道你爲什麼使用WHERE IN作爲一個值 - '$ tagid [0] - > id'。這是否返回一個數組或什麼? 這是一個替代解決方案http://stackoverflow.com/questions/26913776/laravel-4-add-wherein-clause-to-a-join-condition –

回答

0

這項工作對我來說:

DB ::表( 'wouter_blog_posts') - > whereNotNull( '出版') - >在哪裏( '出版',1) - > whereNotNull(」 published_at ') - > whereRaw(' published_at < NOW()') - > whereRaw(「(SELECT COUNT(*)FROM wouter_blog_tags INNER JOIN wouter_blog_posts_tags ON wouter_blog_tagsid = wouter_blog_posts_tagstags_id。 0 WHERE wouter_blog_posts_tagspost_id = wouter_blog_postsid AND id IN( ' 「$標籤識別。」' ))> = 1" ) - > ORDERBY( 'published_at', '降序') - >跳過(0) - >取(10 ) - > PAGINATE($這個 - >屬性( 'postsPerPage')); - '?ID IN'

0

下面的查詢生成器的代碼會給你你中有確切的SQL查詢您的DB::select

DB::table('wouter_blog_posts') 
    ->whereNotNull('published') 
    ->where('published', 1) 
    ->whereNotNull('published_at') 
    ->whereRaw('`published_at` < NOW()') 
    ->where(DB::raw('1'), '<=', function ($query) use ($tagid) { 
     $query->from('wouter_blog_tags') 
      ->select('count(*)') 
      ->join('wouter_blog_posts_tags', 'wouter_blog_tags.id', '=', 'wouter_blog_posts_tags.tags_id') 
      ->whereRaw('`wouter_blog_posts_tags`.`post_id` = `wouter_blog_posts`.`id`') 
      ->whereIn('id', [$tagid[0]->id]); 
    }) 
    ->orderBy('published_at', 'desc') 
    ->skip(0) 
    ->take(10) 
    ->get(); 

子查詢條件必須扭轉,因爲你不能有一個子查詢作爲的第一個參數where方法並仍然能夠綁定條件值。所以它是1 <= (subquery),相當於(subquery) >= 1。創建更復雜的查詢時,是先創建它們並嘗試出來的SQL環境,以確保他們的工作爲indended

SELECT * 
FROM `wouter_blog_posts` 
WHERE `published` IS NOT NULL 
     AND `published` = 1 
     AND `published_at` IS NOT NULL 
     AND `published_at` < Now() 
     AND 1 <= (SELECT `count(*)` 
       FROM `wouter_blog_tags` 
         INNER JOIN `wouter_blog_posts_tags` 
           ON `wouter_blog_tags`.`id` = 
           `wouter_blog_posts_tags`.`tags_id` 
       WHERE `wouter_blog_posts_tags`.`post_id` = 
         `wouter_blog_posts`.`id` 
         AND `id` IN (?)) 
ORDER BY `published_at` DESC 
LIMIT 10 offset 0 

我的過程:通過上面的代碼生成的查詢將這個樣子。然後我用查詢生成器一步一步地實現它們,但是在查詢結束時使用get()而不是get(),我使用toSql()這會給我一個由查詢生成器生成的查詢的字符串表示,允許我比較這對我原來的查詢,以確保它是相同的。

+0

查詢生成器的工作原理與我所期望的完全不同。我不明白: - >'1','<=',函數($ query)使用($ tagid [0] - > id)。沒有colum 1我得到的錯誤:語法錯誤,意外的''1''(T_CONSTANT_ENCAPSED_STRING),等待標識符(T_STRING)或變量(T_VARIABLE)或'{'或'$' – Wouter

+0

這是我的錯誤, t注意到,因爲我反轉了這個條件,所以'where'方法的第一個參數被引用,因爲它期望在那裏有一列。我更新了我的答案,使用'DB :: raw'修復了這個問題。 – Bogdan