Выбор отдельных данных таблицы JOIN в CakePHP - PullRequest
0 голосов
/ 20 марта 2012

У нас есть механизм, который позволяет пользователю просматривать доступные ускорители (вложения) для заданной строки AsapStructure (Node). Они могут привязать несколько ускорителей к этому отдельному узлу.

У меня есть две таблицы, которые имеют отношение многие ко многим (Имеет и принадлежит Многим)

AsapStructure hasAndBelongsToMany Accelerators

Эти две таблицы объединены через accelerators_nodes.

Уменьшенная схема выглядит следующим образом:

AsapStructure:

  • ID
  • название
  • progress_status
  • 1025 * создан *
  • изменен

Ускорители:

  • ID
  • название
  • progress_status
  • 1041 * создан *
  • изменен

accelerators_nodes (Присоединиться к таблице)

  • ID * * тысяча пятьдесят-одна
  • node_id
  • accelerator_id
  • progress_status
  • 1059 * создан *
  • изменен

То, что я пытаюсь сделать, это выбрать все «Ускорители», у которых есть progress_status, равный 5, и связанный с ним узел (AsapStructure - ЕСЛИ он существует. Если он равен NULL, я хочу вернуть ускоритель в любом случае, это просто означает что там нет отношений еще)

В каждой таблице есть поле progress_status, это просто информация об этой конкретной строке. В случае таблиц AsapStructure / Accelerator это просто указывает, утвержден ли этот документ.

Для таблицы соединений progress_status указывает, было ли это отношение одобрено.

Сгенерированный мною SQL приближается, но он выбирает повторяющиеся записи следующим образом:

SELECT 

    AsapStructure.id,
    AsapAccelerator.id,
    AsapAccelerator.foreign_id,
    AsapAccelerator.title,
    AcceleratorsNode.progress_status,
    AsapAccelerator.filename,
    AsapAccelerator.filesize,
    AsapAccelerator.language,
    AsapAccelerator.doctype,
    AsapAccelerator.progress_status,
    AsapAccelerator.modified
FROM
    accelerators AS AsapAccelerator
        left JOIN
    accelerators_nodes AS AcceleratorsNode ON (AcceleratorsNode.accelerator_id = AsapAccelerator.id)
        left JOIN
    asap_structure AS AsapStructure ON (AcceleratorsNode.node_id = AsapStructure.id)
WHERE
    AsapAccelerator.progress_status = 5
ORDER BY AsapStructure.id ASC, AsapAccelerator.title ASC
LIMIT 50    

Пример вывода

    +------+------+------------+---------------------------------+-----------------+-------------------------------------------------------------------+----------+----------+---------------+-----------------+---------------------+
    | id   | id   | foreign_id | title                           | progress_status | filename                                                          | filesize | language | doctype       | progress_status | modified            |
    +------+------+------------+---------------------------------+-----------------+-------------------------------------------------------------------+----------+----------+---------------+-----------------+---------------------+
    | NULL | 1963 |       1211 | Value Delivery Scorecard        |            NULL | 484_Value_Delivery_Status_Project_Scorecard_Template_MS_Draft.doc |   113152 | English  | Template Form |               5 | 2012-03-05 23:56:53 |
    |    1 | 1686 |        933 | Going Live Check Sample Report  |               4 | 459_SAP_GoingLive_Check_Analysis_Session_Sample_Report.doc        |   779264 | English  | Sample        |               5 | 2012-03-05 23:56:21 |
    |    1 | 1792 |       1100 | Preliminary Cutover Strategy    |               4 | 471_Preliminary_Cutover_Strategy.ppt                              |  1070080 | English  | Presentation  |               5 | 2012-03-05 23:56:33 |
    |  933 | 1686 |        933 | Going Live Check Sample Report  |               5 | 459_SAP_GoingLive_Check_Analysis_Session_Sample_Report.doc        |   779264 | English  | Sample        |               5 | 2012-03-05 23:56:21 |
    | 1100 | 1792 |       1100 | Preliminary Cutover Strategy    |               5 | 471_Preliminary_Cutover_Strategy.ppt                              |  1070080 | English  | Presentation  |               5 | 2012-03-05 23:56:33 |
    | 1151 | 1894 |       1151 | Cutover Communications          |               5 | 56_Cutover_Communications.xls                                     |   120320 | English  | Template Form |               5 | 2012-03-05 23:56:45 |
    +------+------+------------+---------------------------------+-----------------+-------------------------------------------------------------------+----------+----------+---------------+-----------------+---------------------+

Как видите, столбец SECOND id содержит идентификатор ускорителя. Первый столбец id - это идентификатор строки AsapStructure. Вы можете видеть, что во втором id поле есть повторяющиеся строки, 1686 и 1792 соответственно.

В первой строке вы видите, что первое поле id имеет значение NULL, это просто означает, что нет никакой связи между строкой AsapStructure и этим ускорителем.

Моя цель

Я хочу выбрать ВСЕ доступные ускорители, независимо от того, подключен ли он к строке AsapStructure. Если он присоединен к строке AsapStructure - я ТОЛЬКО хочу вернуть его, если он соответствует XX (идентификатор узла документа, который они просматривают и хотят добавить вложения [Ускорители]), в противном случае возвращает NULL.

Причина этого в том, что мы отображаем список, разбитый на страницы, и элементы в этом списке будут отображать статус отношений, ЕСЛИ они существуют. Если его не существует, мы просто даем им возможность принять меры по этому пункту.

Желаемый результат

Вот (требуемый) вывод SQL-запроса, поскольку вы видите, что он выбирает уникальные записи, а также обратите внимание на id первого поля id.

    +------+------+------------+---------------------------------+-----------------+-------------------------------------------------------------------+----------+----------+---------------+-----------------+---------------------+
    | id   | id   | foreign_id | title                           | progress_status | filename                                                          | filesize | language | doctype       | progress_status | modified            |
    +------+------+------------+---------------------------------+-----------------+-------------------------------------------------------------------+----------+----------+---------------+-----------------+---------------------+
    | NULL | 1963 |       1211 | Value Delivery Scorecard        |            NULL | 484_Value_Delivery_Status_Project_Scorecard_Template_MS_Draft.doc |   113152 | English  | Template Form |               5 | 2012-03-05 23:56:53 |
    |    1 | 1686 |        933 | Going Live Check Sample Report  |               4 | 459_SAP_GoingLive_Check_Analysis_Session_Sample_Report.doc        |   779264 | English  | Sample        |               5 | 2012-03-05 23:56:21 |
    |    1 | 1792 |       1100 | Preliminary Cutover Strategy    |               4 | 471_Preliminary_Cutover_Strategy.ppt                              |  1070080 | English  | Presentation  |               5 | 2012-03-05 23:56:33 |
    | NULL | 1894 |       1151 | Cutover Communications          |               5 | 56_Cutover_Communications.xls                                     |   120320 | English  | Template Form |               5 | 2012-03-05 23:56:45 |
    +------+------+------------+---------------------------------+-----------------+-------------------------------------------------------------------+----------+----------+---------------+-----------------+---------------------+

Таким образом, когда мы перебираем данные, мы можем легко определить:

  • Если он связан с документом
  • Если это связано с документом, то мы можем определить статус этих отношений.

Если есть более простой способ сделать это, я хотел бы услышать это!

1 Ответ

0 голосов
/ 22 марта 2012

Вы пробовали группировать по идентификатору акселератора?

SELECT 

    AsapStructure.id,
    AsapAccelerator.id,
    AsapAccelerator.foreign_id,
    AsapAccelerator.title,
    AcceleratorsNode.progress_status,
    AsapAccelerator.filename,
    AsapAccelerator.filesize,
    AsapAccelerator.language,
    AsapAccelerator.doctype,
    AsapAccelerator.progress_status,
    AsapAccelerator.modified
FROM
    accelerators AS AsapAccelerator
        left JOIN
    accelerators_nodes AS AcceleratorsNode ON (AcceleratorsNode.accelerator_id = AsapAccelerator.id)
        left JOIN
    asap_structure AS AsapStructure ON (AcceleratorsNode.node_id = AsapStructure.id)
WHERE
    AsapAccelerator.progress_status = 5
GROUP BY AsapAccelerator.id
ORDER BY AsapStructure.id ASC, AsapAccelerator.title ASC
LIMIT 50    
...