2016-12-08 4 views
1

Сценарий: У меня есть таблица заданий, которую я хочу получить. Каждое задание имеет один или несколько связанных с ним элементов, которые хранятся в таблице jobItems. Код и данные элемента сохраняются в таблице элементов. Между заданиями и таблицами jobItems существует взаимосвязь «один ко многим». Также имейте в виду, он имеет большой набор данных.Как фильтровать записи на основе определенного значения в подзапросе?

Я хочу показать все задания, у которых есть один конкретный элемент в их jobItems.

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 на jobItems.jobId, которые являются crea проблемы при внедрении фильтра заданий на основе этого элемента.

Пробовал Опции:

  • Я попытался удалить GROUP BY и GROUP_CONCAT, поэтому он будет возвращать все возможные комбинации рабочих мест элементов. Я решил манипулировать ими , используя php на бэкэнд. Но у него есть один недостаток, что он нарушает разбиение на страницы .
  • Я также попытался динамически изменять LEFT JOIN в INNER JOIN и внутри подзапроса, я добавил условие на INNER JOIN INNER JOIN элементы ON jobItems.itemId = items.id И jobItems.itemId В (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

Это не будет работать, если min 'itemId' окажется меньше единицы. –

+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 раз за каждый товар –

Смежные вопросы