2009-08-31 2 views
3

Это очень важный запрос SQL, после которого основан весь мой сайт ..Сложная строка SQL Query внутреннее соединение общим знаменателем

и ее не работает ..

Его трудно объяснить без примера ..

Есть 2 стола, один из них является составным, а другой - продуктом.

В IngredentsTable я следующее

  1. Хлеб
  2. ChickenBreast
  3. Лапша
  4. майонез
  5. Сыр
  6. Кетчуп
  7. Масло

И ProductsTable

  1. Spageti
  2. Куриная грудка сэндвич

И есть КАРТ TABLE, который соединяет обе таблицы. Он имеет IngredientID и ProductID

Теперь Mapping стол Куриная грудка Sandwich - Хлеб

Куриная грудка сэндвич - Майонез

Куриная грудка сэндвич - Сыр

Куриная грудка Sandwich - Кетчуп

Spageti --- Лапша

Spageti --- Сыр

Spageti --- Ketcup

Вы заметите, что сыр и кетчуп общие записи в обоих куриной грудкой и Spageti

Я хочу написать запрос SQL, который получает ИДЕНТИФИКАЦИИ ПРОДУКТОВ, КОТОРЫЕ ИМЕЮТ УКАЗАННЫЕ ИНГРЕДИЕНТЫ.

Я смог достичь этого частично с помощью следующего запроса

SELECT 
    ProductTable.id, 
    ProductTable.Name 
FROM ProductTable 
INNER JOIN MappingTable 
    ON ProductTable.id = MappingTable.ProductID 
WHERE MappingTable.IngredientID = 5; 

Пусть 5 был сыр, я успешно смог получить результаты куриной грудки Sandwich и Spageti

Но если я добавить Еще один, WHERE MappingTable.ИнгредиентID = 5,6; 6 Хлеб, это должно только показать мне куриный грудной сэндвич и НЕ Spageti

Я получаю ошибку "," синтаксис .. даже "и" не получает результатов.

Как проверить несколько ингредиентов, таких как WHERE MappingTable.IngredientID = 5,6,7;

ЛЮБАЯ ПОМОЩЬ ВЕЛИКОЕ ПРИЗНАНА !!!

мне нужно иметь это в одном запросе ..

Пожалуйста, покажите мне варианты

ответ

3

С 2 запросов можно использовать intesection ваших результатов

Но вы говорите, что вы хотите в одном запросе.

Близкое приближение состоит в том, чтобы иметь групповой оператор и подсчитать количество строк, полученных от вашего результата. Он должен быть равен количеству ваших ингредиентов. Это не сработает, если ваши ингредиенты повторяются несколько раз в одном и том же продукте.

что-то вдоль этой линии на 2 Ингредиенте идентификаторов:

SELECT ProductTable.id, ProductTable.Name FROM ProductTable 
INNER JOIN MappingTable ON ProductTable.id = MappingTable.ProductID 
WHERE MappingTable.IngredientID in (5,6) group by ProductTable.id, ProductTable.Name 
HAVING count(*) = 2; 
+0

Это тоже работает :) спасибо dimus – user134611

1
WHERE MappingTable.IngredientID IN (5, 6, 7) 

К сожалению, мой плохой. Как об этом ?:

SELECT 
    p.id, 
    p.Name 
FROM ProductTable p 
INNER JOIN (SELECT * FROM MappingTable WHERE IngredientID IN (5, 6, 7)) m 
    ON p.id = m.ProductID 
+1

Я так не думаю ...При этом любой продукт с 5 ИЛИ 6 пройдет, а не с 5 И 6 и –

+0

Его не работает таким образом .. Ответит ли SQLite ??? – user134611

0

Вы должны связать с таблицей отображения индивидуально для каждого ингредиента:

SELECT 
    ProductTable.id, 
    ProductTable.Name 
FROM ProductTable 
INNER JOIN MappingTable AS MappingTable1 
    ON ProductTable.id = MappingTable1.ProductID 
    AND MappingTable1.IngredientID = 5 
INNER JOIN MappingTable AS MappingTable2 
    ON ProductTable.id = MappingTable2.ProductID 
    AND MappingTable2.IngredientID = 6 

Если вы используете оператор, как и другие плакаты предложили, вы получите как спагетти и куриный сэндвич для хлеба и сыра, потому что IN по сути является запросом типа OR.

1

Прежде всего, изменить свой вопрос, так что данные в вашем примере таблицах соответствуют примеру вопрос ... Если 5 сыр и 6 Хлеб , затем сравните таблицу ингредиентов. это сбивает с толку иначе.

Во-вторых, вы заявляете, что «это должно показать мне только куриный грудной сэндвич и НЕ Спагетти» заставляет меня думать, что вы хотите знать продукты, в которых есть ВСЕ перечисленные инфидиенты, а не ЛЮБОЙ из них. Если да, то вы хотите следующей

Select P.id, P.Name 
    FROM ProductTable P 
    Where Exists (Select * From Mapping Table 
       Where ProductId = P.ProductId 
        And IngredientId = 5) 
    And Exists (Select * From Mapping Table 
       Where ProductId = P.ProductId 
        And IngredientId = 6) 
    And Exists (Select * From Mapping Table 
       Where ProductId = P.ProductId 
        And IngredientId = 7) 

или, us8ng подсчета логики:

Select P.id, P.Name 
    From ProductTable P 
    Where (Select Count(Distinct IngredientId) 
      From MappingTable M 
      Where ProductId = P.ProductId 
      And IngredientId In (5,6,7)) = 3 
+0

отредактировал вопрос, и у него это получилось, он отлично поработал с первым запросом, хотя и не с обратной логикой – user134611

0

Это должно работать, хотя вы должны поставить две «переменные» в ней - первое это разделенный запятыми набор Ингредиентов, второй (@IngredientsCount) - количество ингредиентов в этом списке.

SELECT ProductsTable.id, ProductTable.Name 
FROM ProductsTable 
INNER JOIN (SELECT ProductID, Count(*) AS Ingredients 
    FROM MappingTable 
    WHERE IngredientID IN (...ids of ingredients here...) 
    GROUP BY ProductID 
    HAVING Count(*) = @IngredientsCount) AS ProductIngredients ON ProductsTable.ProductID = ProductIngredients.ProductID 

Если это возможно то же ингредиент должен быть записан дважды (хотя ваша структура таблицы не выглядит она позволяет это, и это, вероятно, не нужно), переключите два Count (*) для графа (DISTINCT IngredientID) и измените значение @IngredientCount на количество различных используемых ингредиентов.