簡體   English   中英

SQL RIGHT JOIN的誤解

[英]SQL RIGHT JOIN misunderstanding

我正在使用ASP.NET應用程序,該應用程序的SQL后端(MySQL 5.6)具有4個表:第一個表是以這種方式定義的:

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`)
);

這些是項目管理所需的文件。 每個“項目”可以有0個或多個文件(“ id_item”字段填充有“項目”表的有效“ 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`)
);

顧名思義,此表是一個清單。 它描述了需要為特定的“方式”收集哪些文件類型,“方式”字段與“項目”表中的“方式”具有相同的值,“ 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

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

以下查詢為您提供每個項目的狀態,如下所示(清單的種類)。 我必須更改一些列名,這些列名是測試環境中的保留字。

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

嘗試這個:

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);

我已經創建並填充了表格,但是我的要求(針對每個item )和示例輸出(針對每種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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM