Как я могу улучшить этот SQL, чтобы избежать нескольких проблем с его результатами? - PullRequest
0 голосов
/ 02 января 2011

У меня возникли проблемы с поиском.В настоящее время это будет возвращать только результаты, которые имеют по крайней мере 1 строку в таблице maintenance_parts.Я хотел бы, чтобы он возвращал результаты, даже если в строке 0 частей.

Моя вторая проблема заключается в том, что при поиске транспортного средства, которое должно выдать несколько результатов (несколько строк обслуживания), будет возвращен только 1 результат для этого транспортного средства.: У пользователя есть 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"

1 Ответ

1 голос
/ 02 января 2011

Ваш код выполняет JOIN между Maintenance и Maintenace_parts. Первое, что вам нужно сделать, это преобразовать это в LEFT JOIN

  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...

. После этого вы получите нулевые значения для каждого столбца вmaintenance_parts, если подходящая строка не найдена.Похоже, ваш код будет в порядке с этим, но убедитесь, что функция выбора и условия предложения MATCH правильно работают с NULL

Код для проверки / просмотра, который работает правильно с NULLS, следующий

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

Вторая проблема заключается в том, что вы группируете по maintenance_id вместо truck_id .Попробуйте изменить поле GROUP BY, оно должно решить вашу вторую проблему

Пересмотренный запрос ниже

    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"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...