2016-12-08 121 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次 –