在CakePHP中选择不同的JOIN表数据

时间:2012-03-20 08:49:26

标签: mysql cakephp join cakephp-1.3 has-and-belongs-to-many

我们有一种机制允许用户查看给定AsapStructure行(节点)的可用加速器(附件)。他们可以将多个加速器绑定到该单个节点。

我有两个表是多对多的关系(Has并且属于Many)

AsapStructure hasAndBelongsToMany Accelerators

这两个表通过accelerators_nodes加入。

按比例缩小的架构如下:

AsapStructure:

  • ID
  • 标题
  • progress_status
  • 创建
  • 修饰

加速器:

  • ID
  • 标题
  • progress_status
  • 创建
  • 修饰

accelerators_nodes(加入表格)

  • ID
  • NODE_ID
  • accelerator_id
  • progress_status
  • 创建
  • 修饰

我要做的是,选择所有progress_status为5的'加速器'和关联的节点(AsapStructure - 如果它存在。如果它是NULL,我想要返回加速器,它只是意味着没有关系YET)

每个表都有一个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。第一个id列是AsapStructure行的ID。您可以看到第二个id字段中分别有重复的行,分别为1686和1792。

第一行,您可以看到第一个id字段为NULL,这只是意味着AsapStructure行与该加速器之间没有关系。

我的目标

我想选择所有可用的加速器,无论它是否附加到AsapStructure行。如果它附加到AsapStructure行 - 我只想返回它,如果它匹配XX(他们正在查看的文档的节点ID,并希望添加附件[加速器]),否则返回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 :(得分:0)

您是否尝试按加速器ID进行分组?

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