2016-06-04 2 views
0

Я должен таблиц SQL:Выберите данные из таблиц

Таблица 1 (Recipes):

Name  Ingredients 
---------------------------------- 
ciorba  apa,sare,piper,branza 
paste  branza,oua,lapte 

Таблица 2 (Ingredients понравилось пользователем):

Name  Ingredients 
------------------------- 
ionutG  branza 
vasile  oua,lapte 

Я хочу, чтобы выбрать рецепты из таблицы 1, которая содержит одну или более любимых ингредиентов из таблицы 2.

Ex : Для ionutG я хочу получить оба рецепта, потому что есть любимые ингредиенты. И для vasile я хочу получить только второй рецепт.

Обратите внимание, что таблицы больше и количество записей очень велико.

Вот что я пробовал:

SELECT 
    a.Nume 
FROM 
    reteta a 
JOIN 
    ingredientplacut b ON (a.Ingrediente = b.Ingrediente); 

Но он возвращает мне только рецепты, которые имеют точные и те же ингредиенты, которые я не хочу. Я хочу вернуть рецепты, которые содержат один или несколько ингредиентов, не всех.

Благодаря

+3

Ваша проблема заключается в том, что вы храните списки элементов в виде строки. Это плохая идея. Исправьте структуру данных, чтобы использовать таблицы соединений, и SQL будет (относительно) легким. –

+0

Я не думаю, что это решение для моей проблемы, потому что один пользователь может иметь так много любимых ингредиентов, что означает один ряд в таблице для каждого понравившегося ингредиента. Возможно, я ошибаюсь, и вы можете дать мне решение, если вы Хорошо. Вы можете использовать таблицы, описанные выше. – Bogdan

+2

Гордон прав. Вы должны прочитать «нормализацию». У вас есть отношения «многие ко многим», которые должны быть смоделированы с помощью таблицы ссылок между рецептами и ингредиентами. Также: какие СУБД вы используете? –

ответ

0

Try существует как, например

Select a.name from table 1 where exists (select b.name from table 2 where a.ingredient = b.name); 

Пожалуйста, обратите внимание, что это может быть не правильный синтаксис. Таким образом, он возвращает все рецепты, где существует, возвращает true. Поэтому, когда один или несколько ингредиентов одинаковы.

+0

Это не работает, ничего не возвращает – Bogdan

0

Если вы настаиваете на хранение данных, как вы делаете, возможное решение (проверено в T-SQL, вопрос не определяет SQL вкус):

Настройка

create table Recipes 
(
    RecipeId INT NOT NULL IDENTITY(1, 1) CONSTRAINT PK_Recipes PRIMARY KEY, 
    Name NVARCHAR(100), 
    Ingredients NVARCHAR(4000) 
) 
GO 

insert into Recipes (Name, Ingredients) VALUES ('ciorba', 'apa,sare,piper,branza'), ('paste', 'branza,oua,lapte') 
GO 


create table Ingredients 
(
    IngredientId INT NOT NULL IDENTITY(1, 1) CONSTRAINT PK_Ingredients PRIMARY KEY, 
    Name NVARCHAR(100), 
    Ingredients NVARCHAR(4000) 
) 
GO 

insert into Ingredients (Name, Ingredients) VALUES ('ionutG', 'branza'), ('vasile', 'oua,lapte') 
GO 

- не помню что является источником для этого - вероятно this

CREATE FUNCTION [dbo].[SplitStrings_XML] 
(
    @List  NVARCHAR(MAX), 
    @Delimiter NVARCHAR(255) 
) 
RETURNS TABLE 
WITH SCHEMABINDING 
AS 
    RETURN 
    ( 
     SELECT Item = y.i.value('(./text())[1]', 'nvarchar(4000)') 
     FROM 
     ( 
     SELECT x = CONVERT(XML, '<i>' 
      + REPLACE(@List, @Delimiter, '</i><i>') 
      + '</i>').query('.') 
    ) AS a CROSS APPLY x.nodes('i') AS y(i) 
    ); 

GO 

select * from Recipes 
select * from Ingredients 
GO 

-- split strings and retrieve records where intersection is not null 
select distinct I.Name, I.Ingredients, R.Name 
FROM Ingredients I 
    CROSS APPLY dbo.SplitStrings_XML(Ingredients, ',') IToken 
JOIN Recipes R 
    CROSS APPLY dbo.SplitStrings_XML(Ingredients, ',') RToken 
     ON RToken.Item = IToken.Item 

Примечание:. Как уже упоминалось, вы действительно должны рассмотреть нормализации ваши данные:

1) Производительность - строковые операции являются дорогостоящими и их следует избегать

2) Трудно писать запросы - основной запрос для выяснения общие элементы используют определенную пользователем функцию

3) Плохо для разработки приложений - считают, что клиенту также требуется английская версия приложения. В настоящее время все позиции находятся на румынском языке. Как вам справиться с этой ситуацией?

4) Плохо для отчетов - считайте, что ваша структура требует обширного запроса отчетов об использовании ингредиентов и другой информации.Эти отчеты будут иметь сложные и запутанные вопросы, которые будут медленно

[EDIT] Для MySQL следующих ссылок могут быть использованы для замены неподдерживаемых функций, описанных выше:

Разделить строки, используя метод, показанный here. Связанные вопросы и ответы here и here.

+0

Я не могу хранить ингредиенты рецепта в несколько рядов, все ингредиенты будут храниться в одной строке. Также я могу хранить понравившиеся ингредиенты в одну или несколько строк. Так что у меня есть найти решение для сравнения этих строк, и если они соответствуют частичным или нет, мне нужно выбрать этот рецепт. – Bogdan

+0

Почему бы и нет? Вы можете иметь таблицу «Ингредиенты» и определять таблицы X: «RecipeXIngredient» и «UserXIngredient». Таблицы X будут использовать только идентификаторы (целые числа), а запросы проще. Кроме того, пространство, используемое таблицами, значительно меньше. – Alexei

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