2016-12-08 120 views
1

場景: 我有一張我想要取的作業表。每個作業都有一個或多個與它關聯的項目,這些項目存儲在jobItems表中。項目的代碼和細節保存在項目表中。 job和jobItems表之間有一對多的關係。還要記住,它有很大的數據集。如何根據子查詢中的特定值篩選記錄?

我想顯示在jobItem中有一個特定項目的所有工作。

MySQL的小提琴:http://sqlfiddle.com/#!9/4a5a47

模式:

CREATE TABLE jobs (
    `id` INT, 
    `jobRef` VARCHAR (55) 
); 

INSERT INTO jobs (`id`, `jobRef`) 
VALUES 
    (1, 'job1'), 
    (2, 'job2'), 
    (3, 'job3'); 

CREATE TABLE jobItems (
    `id` INT, 
    `itemId` INT, 
    `jobId` INT 
); 

INSERT INTO jobItems (`id`, `itemId`, `jobId`) 
VALUES 
    (1, 1, 1), 
    (2, 2, 1), 
    (3, 3, 1), 
    (4, 1, 2), 
    (5, 2, 2), 
    (6, 3, 3); 

CREATE TABLE items (
    `id` INT, 
    `itemCode` VARCHAR (55) 
); 

INSERT INTO items (`id`, `itemCode`) 
VALUES 
    (1, 'item1'), 
    (2, 'item2'), 
    (3, 'item3'); 

查詢:

SELECT 
    jobs.*, ji.allItems 
FROM 
    jobs 
LEFT JOIN (
    SELECT 
     jobItems.jobId, 
     GROUP_CONCAT(items.itemCode) AS allItems 
    FROM 
     jobItems 
    INNER JOIN items ON jobItems.itemId = items.id 
    GROUP BY 
     jobItems.jobId 
) AS ji ON ji.jobId = jobs.id 

正如你注意到沒有,有一個LEFT JOIN以及一個GROUP BY作爲crea的jobItems.jobId在實施這個基於項目的工作過濾器時遇到問題。

嘗試選項:

  • 我試圖刪除GROUP BY和GROUP_CONCAT,所以它會返回 所有可能的工作項目組合。我想在後端使用php來操縱它們 。但它有一個缺點,它擾亂了 分頁。
  • 我也試着動態地將左加入變成INNER JOIN和 在子查詢中,我在INNER JOIN INNER JOIN上添加了一個條件ON jobItems.itemId = items.id AND jobItems.itemId IN(1)但是, 由於GROUP BY,它不會獲取所需的結果,因爲它將只返回只有一個具有給定itemId的項目的作業。 不退還其與 的itemId = 1

總之多個項目,包括項目的工作,我希望獲取其具有含的itemId = 1項項目的所有作業和預期的結果是JOB1和job2,因爲他們都有item1。

+1

您的預期結果是什麼? – Madhivanan

+0

@Madhivanan我編輯了這個問題,並在其中添加了預期的結果。 –

+0

job3有item1,FYI –

回答

2

試試這個

SELECT jobs.*, ji.allItems 
FROM jobs 
INNER JOIN (
    SELECT 
     jobItems.jobId, 
     GROUP_CONCAT(items.itemCode) AS allItems 
    FROM 
     jobItems 
    INNER JOIN items ON jobItems.itemId = items.id 
    GROUP BY 
     jobItems.jobId 
    HAVING MAX(CASE WHEN jobItems.itemId = 1 THEN 1 ELSE 0 END) > 0 
) AS ji ON ji.jobId = jobs.id 

SQLFiddle

對於多個項目的過濾器(例如,你要找到這兩個項目1相關的作業和2)

SELECT jobs.*, ji.allItems 
FROM jobs 
INNER JOIN (
    SELECT 
     jobItems.jobId, 
     GROUP_CONCAT(items.itemCode) AS allItems 
    FROM 
     jobItems 
    INNER JOIN items ON jobItems.itemId = items.id 
    GROUP BY 
     jobItems.jobId 
    HAVING 
    MAX(CASE WHEN jobItems.itemId = 1 THEN 1 ELSE 0 END) > 0 AND 
    MAX(CASE WHEN jobItems.itemId = 2 THEN 1 ELSE 0 END) > 0 
) AS ji ON ji.jobId = jobs.id 
+0

如果最小'itemId'恰好小於1,這將不起作用。 –

+0

是的。我修改了不同的 – Madhivanan

+0

它的工作。我們可以將它轉換爲像IN條件一樣對多個項目進行過濾嗎? –

0

這是對你的工作。

select j.*, i.itemCode from jobs j 
inner join jobItems m on m.jobid = j.id 
inner join items i on i.id = m.itemId 
where exists (select 'x' from jobItems a 
       where a.itemId = 2 
       and a.jobId = j.id) 

希望你想得到的工作,哪些特定項目綁定。

讓我知道我是否想知道您的要求。

http://sqlfiddle.com/#!9/4a5a47/11

+0

我還需要顯示所有與作業關聯的項目,它不會抓取。 –

+0

我做了一些更改。請檢查,並讓我知道這是爲你的工作 –

+0

其多次返回工作。每個項目1次 –