2011-01-02 7 views
0

検索に問題があります。現在のところ、これはmaintenance_partsテーブルに少なくとも1行ある結果だけを返します。私は0の部分の行があっても結果を返すことを望みます。結果にいくつかの問題が発生しないように、このSQLを改善するにはどうすればよいですか?

私の2番目の問題は、車両を検索し、複数の結果(複数のメンテナンス行)を返さなければならないということです。

背景情報: ユーザーには2つのフィールドがあります。フィールドは車両とキーワードです。車両フィールドは、メイク、モデル、VIN、トラック番号(多くの場合2〜3桁または2桁の数字の後に続く文字)、およびトラックテーブルに属する他のいくつかのフィールドに基づいて検索することができます。このキーワードは、maintenanceおよびmaintenance_partsテーブルのほとんどのフィールド(作業の説明、部品名、部品番号など)を検索するためのものです。

maintenance_partsテーブルには、メンテナンス行ごとに0,1、またはそれ以上の行を含めることができます。トラック表には、各保守行ごとに正確に1つの行が含まれています。トラックには複数のメンテナンス記録を持たせることができます。

"SELECT M.maintenance_id, M.some_id, M.type_code, M.service_date, M.mileage, M.mg_id, M.mg_type, M.comments, M.work_done, 
        MATCH(M.comments, M.work_done) AGAINST('$keywords') + 
        MATCH(P.part_num, P.part_desc, P.part_ref) AGAINST('$keywords') + 
        MATCH(T.truck_number, T.make, T.model, T.engine, T.vin_number, T.transmission_number, T.comments) AGAINST('$vehicle') 
        AS score 
       FROM maintenance M, maintenance_parts P, truck T 
       WHERE M.maintenance_id = P.maintenance_id 
       AND M.some_id = T.truck_id 
       AND M.type_code = 'truck' 
       AND (
        (MATCH(T.truck_number, T.make, T.model, T.engine, T.vin_number, T.transmission_number, T.comments) AGAINST('$vehicle') 
        OR T.truck_number LIKE '%$vehicle%') 
        OR MATCH(P.part_num, P.part_desc, P.part_ref) AGAINST('$keywords') 
        OR MATCH(M.comments, M.work_done) AGAINST('$keywords') 
       ) 
       AND M.status = 'A' GROUP BY maintenance_id ORDER BY score DESC, maintenance_id DESC LIMIT 0, $limit" 
+0

可能重複下記解決する必要があります。 //stackoverflow.com/questions/4576473/what-c​​an-i-do-to-make-this-sql-return-results-in-certain-situations) –

答えて

1

あなたのコードは、あなたが行う必要がありますまず最初にあなたがこれを実行した後、あなたはすべてのためにnull値を取得します

FROM maintenance M 
    JOIN truck T ON t.truck_id=M.some_id 
    LEFT JOIN maintenance_parts P ON M.maintenance_id = P.maintenance_id 
    WHERE... 

を登録しようLEFTにこれを変換しているメンテナンスとMaintenace_parts間のJOINありません一致する行が見つからない場合、maintenance_partsの列。適切に

OR MATCH(P.part_num, P.part_desc, P.part_ref) AGAINST('$keywords') 

以下れるNULLSで正常に動作します/レビューを確認するために、NULL値

コードで動作するコードはこれでOKになります表示されますが、必ずあなたの選択にし、where句のMATCH関数2番目の問題は、maintenance_idの代わりにtruck_idの代わりにグループ化しているようです。フィールド、GROUP BYを変更してみてください、それはあなたの第二の問題

改訂クエリ(HTTP [?私は特定の状況で、このSQL戻り結果を作るために何ができるか]の

SELECT T.TRUCK_ID,M.maintenance_id, M.some_id, M.type_code, M.service_date, 
      M.mileage, M.mg_id, M.mg_type, M.comments, M.work_done, 
      MATCH(M.comments, M.work_done) AGAINST('$keywords') + 
      IfNull(P.PartScore,0) + 
      MATCH(T.truck_number, T.make, T.model, T.engine, T.vin_number, T.transmission_number, T.comments) AGAINST('$vehicle') 
      AS score 
        FROM maintenance M, 
        JOIN 

        (SELECT Truck_id,truck_number, make, model, engine, vin_number,   transmission_number,comments FROM Truck 
UNION 
SELECT Truck_id,truck_number, make, model, engine, vin_number,   transmission_number,comments FROM Trailer 
) 

T 
        ON M.some_id=T.Truck_id 
        LEFT JOIN 
        (SELECT maintenance_id,SUM(MATCH(P.part_num, P.part_desc, P.part_ref)    AGAINST('$keywords')) AS PartScore 
        FROM maintenance_parts 
        GROUP BY maintenance_id) P 
        P ON M.maintenance_id = P.maintenance_id 
        WHERE M.type_code = 'truck' 
        AND (
         (MATCH(T.truck_number, T.make, T.model, T.engine, T.vin_number, T.transmission_number, T.comments) AGAINST('$vehicle') 
         OR T.truck_number LIKE '%$vehicle%') 
         OR MATCH(P.part_num, P.part_desc, P.part_ref) AGAINST('$keywords') 
         OR MATCH(M.comments, M.work_done) AGAINST('$keywords') 
        ) 
        AND M.status = 'A' 
    ORDER BY score DESC, maintenance_id DESC 
    LIMIT 0, $limit" 
+0

私は:#1054 - 不明な列 'M.maintenance_id' 'on clause' –

+1

元のコードがそれを見つけたので、それは驚きです。私はすべてのテーブルのJOINメソッドを使用して変換する答えを編集しましたが、MYSQLにはメソッドを混在させないものがあります。それを試してみてください... – Sparky

+0

また、グループを変更するときは、select句のフィールドmaintenance_idをTRUCK_IDに置き換える必要があります。とにかくGROUP BYを使用しているのですが、それはあなたがそれを必要としないと思われます... – Sparky

関連する問題