2016-04-30 6 views
2

Laravelで生SQLクエリパートを実行する必要があります。Laravelクエリビルダ生ANDステートメント

生のSQLは次のように、基本的になります。

AND (forretningsadresse_fylke = 'HEDMARK' 
    AND (forretningsadresse_kommune = 'HAMAR') 
    OR (forretningsadresse_kommune = 'ELVERUM') 
) 
OR (forretningsadresse_fylke = 'HORDALAND' 
    AND (forretningsadresse_kommune = 'BERGEN') 
) 

私が使用しよう:

$result = Company::where(function($a) use($input, $sql) { 

     // Name or keywords LIKE string 
     $a -> where('navn', 'LIKE', '%'. $input['query_string'] .'%'); 
     $a -> where('keywords', 'LIKE', '%'. $input['query_string'] .'%'); 
     if (!empty($sql)) { 
      $a -> where(DB::statement($sql)); 
     } 

    }); 

    $result = $result -> take($input['limit'])  // Take $limit 
         -> offset($input['offset']) // Offset by $offset 
         -> orderBy('rank', 'DESC')  // Sponsors first 
         -> get(); 

しかし、それは動作しません。以下のエラーを参照してください。 これはどのように機能しますか?前もって感謝します!

Connection.php行のQueryException 673:SQLSTATE [42000]:構文エラーまたはアクセス違反:1064 SQL構文にエラーがあります。 1行目(SQL:AND(fork))の近くで使用する正しい構文についてはMariaDBサーバーのバージョンに対応するマニュアルをチェックしてください。

EDIT:テーブル100万行を持っている、と私は生のクエリを作成するには、このメソッドを使用します。http://i.imgur.com/Q5SRP58.png

+0

あなたは、私がこれを試してみましたフル – oseintow

答えて

1

はあなたのコードには2つの問題があります。

  1. あなたはDB::rawを使用する必要がありますDB::statementを使用しています。 DB::statementは引数として渡す文字列を実行しますが、これは必要なものではありません。クエリビルダに含めるには、生のステートメントを渡す必要があります。
  2. 投稿した生ブロックが$sqlパラメータであると仮定すると、開始ANDを削除する必要があります。そうしないと、クエリは.... and AND (になり、エラーが発生します。この与えられた

、あなたはにあなたのコードを更新する必要があります。

// Notice the removal of the `AND` 
$sql = "(forretningsadresse_fylke = 'HEDMARK' 
     AND (forretningsadresse_kommune = 'HAMAR') 
     OR (forretningsadresse_kommune = 'ELVERUM') 
    ) 
    OR (forretningsadresse_fylke = 'HORDALAND' 
     AND (forretningsadresse_kommune = 'BERGEN') 
    )"; 

$result = Company::where(function($a) use($input, $sql) { 
    // Name or keywords LIKE string 
    $a->where('navn', 'LIKE', '%'. $input['query_string'] .'%'); 
    $a->where('keywords', 'LIKE', '%'. $input['query_string'] .'%'); 
    if (!empty($sql)) { 
     // Using DB::raw instead of DB::statement 
     $a->where(DB::raw($sql)); 
    } 
}); 
+0

でクエリを記述してくださいでき役に立てば幸い

$result = Company::where('navn', 'LIKE', '%'. $input['query_string'] .'%') ->where('keywords', 'LIKE', '%'. $input['query_string'] .'%') ->where(function($query){ $query->where('forretningsadresse_fylke', '=', 'HEDMARK') ->where('forretningsadresse_kommune', '=', 'HAMAR') ->orWhere('forretningsadresse_kommune','=', 'ELVERUM'); }) ->where(function($query){ $query->orWhere('forretningsadresse_fylke','=', 'HORDALAND') ->where('forretningsadresse_kommune', '=', 'BERGEN'); }) ->take($input['limit']) // Take $limit ->offset($input['offset']) // Offset by $offset ->orderBy('rank', 'DESC') // Sponsors first ->get(); 

をお試しくださいしかし、それは30秒の実行時間を極限にしました。それはかなり静かです。テーブルには100万行、20列があります。インデックスを追加する以外にデータベースを最適化する方法はありますか?またはクエリを最適化しますか?しかし、ありがとう。 – Kaizokupuffball

+0

@Kaizokupuffball、もう一つの問題です。最善の方法は、forretningsadresse_fylke'、 'forretningsadresse_kommune'、' navn'、 'keywords'にインデックスを適用することです。しかし、あなたはLIKESを持っているので、その文は実行に時間がかかります。最善の策は、select文を "explain"の前に置くことです。クエリーをプロファイルするために 'explain select * from .... .... 'のようなものがあります。その問題を解決できない場合は、おそらくhttp://dba.stackexchange.com/ –

1

それは

+0

に新しい質問を追加する必要があります。私はこのアプローチを行うことはできないと思います。 私はこの方法で生のSQLを作成します:http://i.imgur.com/Q5SRP58.png これを簡単にする方法を見つけようとしますが、これを行う方法を理解できません。 – Kaizokupuffball