SQL RIGHT JOIN误解

时间:2016-01-03 17:16:37

标签: mysql sql join

我正在研究ASP.NET后端(MySQL 5.6)有4个表的ASP.NET应用程序: 第一个表以这种方式定义:

CREATE TABLE `items` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `descr` varchar(45) NOT NULL,
  `modus` varchar(8) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `id_UNIQUE` (`id`)
);

这些是应用程序中管理的项目。

第二张表:

CREATE TABLE `files` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `file_path` varchar(255) NOT NULL,
  `id_item` int(11) NOT NULL,
  `id_type` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `id_UNIQUE` (`id`)
);

这些是项目管理所需的文件。每个'item'可以包含0个或多个文件('id_item'字段填充了'items'表的有效'id')。

第三张表:

CREATE TABLE `file_types` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `file_type` varchar(32) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `id_UNIQUE` (`id`)
);

此表描述了文件的类型。

第四张表:

CREATE TABLE `checklist` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `id_type` int(11)  NOT NULL,
  `modus` varchar(8) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `id_UNIQUE` (`id`)
);

这个表,正如其名称所示,是一个清单。它描述了需要为特定“modus”收集哪些类型的文件,“modus”字段与'items'表中的'modus'保持相同的值,'id_type'保存'file_types'表中的有效'id'值

我们假设第一个表包含这些项目:

id  descr      modus
--------------------
1   First      M
2   Second     P
3   Third      M
4   Fourth     M
--------------------

第二个:

id  file_path       id_item    id_type
--------------------------------------
1   file1.jpg       1          1
2   file2.jpg       1          2
3   file3.jpg       2          1
4   file4.jpg       1          4
5   file5.jpg       1          1
--------------------------------------

第三个:

id  file_type
--------------
1   red
2   blue
3   green
4   default
--------------

第四张表:

id  id_type    modus
--------------------
1   1          M
2   2          M
3   3          M
4   4          M
5   1          P
6   4          P
--------------------

我需要获得的是一个包含这些项目的表格(参考id_item = 1):

id_item  file_path       id_type   file_type
--------------------------------------------
1        file1.jpg       1         red
1        file5.jpg       1         red
1        file2.jpg       2         blue
1        file4.jpg       4         default
<null>   <null>          3         green
--------------------------------------------

虽然id_item = 2的结果表应如下所示:

id_item  file_path       id_type   file_type
--------------------------------------------
2        file3.jpg       1         red
<null>   <null>          4         default
--------------------------------------------

当然'id_item'是'items'表的'id','id_type'是'types'表的'id'等。

简而言之,我需要有一个表格来描述特定项目'id'的清单状态,即已收集哪些文件,但也缺少哪些文件。

我尝试使用RIGHT JOIN子句但没有成功:

SELECT 
    items.id AS id_item,
    files.file_path AS file_path,
    file_types.id AS id_type,
    file_types.file_type AS file_type
FROM
    files
        RIGHT JOIN
    checklist ON (files.id_type = checklist.id_type )
        INNER JOIN
    items ON (files.id_item = items.id)
        AND (items.modus = checklist.modus)
        INNER JOIN
    file_types ON (checklist.id_type = file_types.id)
WHERE (items.id = 1);

此查询的结果是:

 id_item   file_path    id_type    file_type
 ------------------------------------------
 1         file1.jpg    1          red
 1         file5.jpg    1          red
 1         file2.jpg    2          blue
 1         file4.jpg    4          default

缺少最后一行(清单中缺少的文件)。

3 个答案:

答案 0 :(得分:2)

以下查询会为您提供以下各项目的状态(核对清单类型)。我不得不更改一些在我的测试环境中保留字的列名。

select item_id,
       fp filepath,
       m_type,
       item_desc,
       modee,
       (select t.type from typess t where t.id = m_type)
  from (select null      item_id,
               i.descr   item_desc,
               c.modee   modee,
               c.id_type m_type,
               null      fp
          from items i, checklist c
         where c.modee = i.modee
           and i.id = 0
           and c.id_type not in
               (select f.id_type from files f where f.id_item = i.id)
        union all
        select i.id        item_id,
               i.descr     item_desc,
               c.modee     modee,
               c.id_type   m_type,
               f.file_path fp
          from items i, checklist c, files f
         where c.modee = i.modee
           and i.id = 0
           and f.id_item = i.id
           and f.id_type = c.id_type)
 order by item_id asc, m_type asc

答案 1 :(得分:1)

试试这个:

SELECT 
    files.file_path,
    types.type
FROM files 
LEFT JOIN checklist ON (files.id_type = checklist.id_type )
LEFT JOIN items ON (files.id_item = items.id)
                AND (items.mode = checklist.mode)
LEFT JOIN types ON (checklist.id_type = types .id)
WHERE (items.id = 0);

答案 2 :(得分:1)

我已创建并填充了您的表格,但我在您请求的内容(每个item)与示例输出(每个项目type)之间存在差异。但是,我已根据输出创建了一个查询:

;with cte as (
    SELECT i.id, f.file_path, f.id_type 
    from checklist ck
        JOIN files f on f.id_type = ck.id_type
        JOIN items i on i.id = f.id_item AND i.mode = ck.mode AND i.id = 0
)
SELECT cte.id, cte.file_path, T.id, T.[type]
FROM types T
    LEFT JOIN cte on cte.id_type = T.id

<强> [编辑]

My result is the following (SQL):

id  file_path   id  type
---------------------------------
0   file1.jpg   0   red
0   file5.jpg   0   red
0   file2.jpg   1   blue
NULL    NULL    2   green
0   file4.jpg   3   default

没有CTE版本:

SELECT cte.id, cte.file_path, T.id, T.[type]
FROM types T
    LEFT JOIN (
        SELECT i.id, f.file_path, f.id_type 
        from checklist ck
            JOIN files f on f.id_type = ck.id_type
            JOIN items i on i.id = f.id_item AND i.mode = ck.mode AND i.id = 0
    ) cte on cte.id_type = T.id