2015-09-12 22 views
5

In giorni difficili per capire come posso convertire una query SQL in uno stile generatore di query in laravel.converti query SQL in stile query builder

mia query 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"); 

dove ora finisco per convertire al generatore di query è:

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

Ho letto che non posso utilizzare in cui in un join. L'errore io ora ottenere:

Chiama per metodo non definito Illuminate \ Database \ Query \ JoinClause :: in cui()

io davvero non so come posso convertire il mio SQL per query. Spero che quando vedrò una buona conversione di lavoro della mia domanda, posso capire come devo farlo la prossima volta.

+0

non ho provato questo, ma forse usare '> whereRaw (, [$ TagID [0] -> id]) '. Assicurati solo che il parametro dei bind alla fine sia un array.Tuttavia, non so perché stai usando WHERE IN per un valore - '$ tagid [0] -> id'. Questo restituisce una matrice o qualcosa del genere? Ecco una soluzione alternativa http://stackoverflow.com/questions/26913776/laravel-4-add-wherein-clause-to-a-join-condition –

risposta

0

questo lavoro per me:

DB :: tabella ('') wouter_blog_posts -> whereNotNull ('pubblicato') -> dove ('pubblicato', 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 DOVE wouter_blog_posts_tags. post_id = wouter_blog_posts. id E id IN ( ' "$ TagID.".' ))> = 1") -> orderBy ('published_at', 'desc') -> saltare (0) -> prendere (10) -> paginate ($ this-> proprietà ('postsPerPage')); - '? id IN'

0

il seguente codice Query Builder vi darà la query SQL esatto avete all'interno del vostro 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(); 

La condizione sottoquery doveva essere invertita, perché non si può avere una subquery come primo parametro del Metodo where ed è ancora possibile legare il valore della condizione. Quindi è 1 <= (subquery) che equivale a (subquery) >= 1. La query generato dal codice di cui sopra sarà simile a questa:

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 

Il mio processo per la creazione di query più complesse è quello di creare prima loro e provare in un ambiente SQL per assicurarsi che funzionino come indended. Poi li implemento passo dopo passo con il generatore di query, ma invece di usare get() alla fine della query, io uso toSql() che mi darà una rappresentazione di stringa della query che verrà generata dal generatore di query, permettendomi di confrontare quello alla mia domanda originale per assicurarmi che sia lo stesso.

+0

il generatore di query funziona in modo completamente diverso rispetto a quello che mi aspetterei. Non capisco questo: -> '1', '<=', funzione ($ query) usa ($ tagid [0] -> id). Non c'è colum 1 L'errore che ottengo: errore di sintassi, imprevisto '' 1 '' (T_CONSTANT_ENCAPSED_STRING), identificatore atteso (T_STRING) o variabile (T_VARIABLE) o '{' o '$' – Wouter

+0

Questo è stato un mio errore, non l'ho fatto Si noti che poiché ho invertito la condizione, il primo parametro del metodo 'where' viene quotato perché si aspetta una colonna lì. Ho aggiornato la mia risposta per usare 'DB :: raw' che risolve il problema. – Bogdan