2015-09-12 9 views
5

Próbuję dni, aby zrozumieć, w jaki sposób mogę przekonwertować zapytanie SQL do stylu konstruktora kwerend w laravel.Konwertuj zapytanie SQL do zapytania o styl konstruktora

Moje zapytanie SQL jest:

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

Gdzie ja teraz skończyć przekonwertować do konstruktora zapytań jest:

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

Czytałem, że nie można korzystać z którym w przyłączyć. Błąd teraz uzyskać:

Zaproszenie do metody nieokreślone Illuminate \ database \ Zapytanie \ JoinClause :: gdzie()

ja naprawdę nie wiem, jak mogę przekonwertować do SQL Query Builder. Mam nadzieję, że gdy zobaczę dobrze działającą konwersję mojego zapytania, mogę zrozumieć, jak muszę to zrobić następnym razem.

+0

nie próbowałem tego, ale może używać '> whereRaw ([$ TagID [0] -> id]) '. Tylko upewnij się, że parametr wiązania na końcu jest tablicą.Jednak nie wiem, dlaczego używasz WHERE IN dla jednej wartości - '$ tagid [0] -> id'. Czy to zwraca tablicę lub coś takiego? Oto alternatywne rozwiązanie http://stackoverflow.com/questions/26913776/laravel-4-add-wherein-clause-to-a-join-condition –

Odpowiedz

0

To praca dla mnie:

DB :: tabeli ('') wouter_blog_posts -> whereNotNull ('opublikowany') -> gdzie ('opublikowany', 1) -> whereNotNull (” published_at ') -> whereRaw (' published_at < NOW() ') -> whereRaw ("(SELECT count (*) FROM wouter_blog_tags INNER JOIN wouter_blog_posts_tags NA wouter_blog_tagsid = wouter_blog_posts_tagstags_id.. 0 WHERE wouter_blog_posts_tags. post_id = wouter_blog_posts. id I id IN ( ' "$ TagID.".' ))> = 1") -> orderby ('published_at', 'desc') -> pominąć (0) -> podjąć (10) -> paginate ($ this-> własność ('postsPerPage')); - '? id IN'

0

następujący kod Query Builder daje zapytanie SQL dokładnie masz w swoim 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(); 

Warunkiem Podzapytanie musiały zostać odwrócone, ponieważ nie można mieć podkwerenda jako pierwszy parametr where metoda i nadal być w stanie powiązać wartość warunku. Tak więc jest to 1 <= (subquery), co jest równoważne (subquery) >= 1. Zapytania generowane przez powyższy kod będzie wyglądać następująco:

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 

mój proces przy tworzeniu bardziej złożonych zapytań jest najpierw utworzyć je i je wypróbować w środowisku SQL, aby upewnić się, że działają one jak indended. Następnie wdrażam je krok po kroku za pomocą Konstruktora kwerend, ale zamiast używać get() na końcu zapytania, używam toSql(), która da mi ciąg znaków reprezentujący zapytanie wygenerowane przez Konstruktora kwerend, pozwalające na porównanie to do mojego pierwotnego zapytania, aby upewnić się, że jest to to samo.

+0

Kreator zapytań działa zupełnie inaczej niż się spodziewałam. Nie rozumiem tego: -> '1', '<=', funkcja ($ query) use ($ tagid [0] -> id). Nie ma colum 1 Otrzymuję błąd: błąd składni, nieoczekiwany "1" (T_CONSTANT_ENCAPSED_STRING), oczekujący identyfikatora (T_STRING) lub zmiennej (T_VARIABLE) lub "{" lub "$" – Wouter

+0

To był mój błąd, nie zrobiłem tego " Zauważmy, że ponieważ odwróciłem warunek, pierwszy parametr metody "where" zostaje zacytowany, ponieważ oczekuje tam kolumny. Zaktualizowałem swoją odpowiedź, aby użyć 'DB :: raw', która to rozwiązuje. – Bogdan

Powiązane problemy