I need to select a recipe and its ingredients without repeating the other recipe fields

0

I have the following scenario:

Recipe Table
---------------------
id name
preparation mode
category

Ingredient Table
--------------------------
id name

Ingredient_receive table
--------------------------------------
id id_receita
id_ingrediente

I want to make a select that brings the recipes with their ingredients according to the ingredients that I inform.

Eg: select recipes that contain flour, egg and sugar (I want you to bring recipes that have only those 3 ingredients, if the recipe has any other ingredients, I do not want it to appear)

Assuming that a carrot cake only has these 3 ingredients

I do not want you to bring it like this:

1 | Carrot cake | preparation mode: blablabla | Category: Sweets | flour
1 | Carrot cake | preparation mode: blablabla | Category: Sweets | egg
1 | Carrot cake | preparation mode: blablabla | Category: Sweets | sugar

I want you to bring it like this (All on the same line):

1 | Carrot cake | preparation mode: blablabla | Category: Sweets | flour | egg | sugar

Database: Mysql

Can you help me? Thank you.

    
asked by anonymous 24.11.2017 / 17:28

2 answers

2

We will need 2 parameters, the id's of the ingredients we are going to look for and the amount of ingredients being sought. Here we will do the following:

Test table structure:

CREATE TABLE receita(id int, nome varchar(20), preparo varchar(20), categoria int);
CREATE TABLE ingrediente(id int, nome varchar(50));
CREATE TABLE ingrediente_receita(id int, id_receita int, id_ingrediente int);

INSERT INTO receita VALUES(1,'bolo','teste',1);

INSERT INTO ingrediente values(1, 'farinha'),(2,'açucar'),(3,'ovo');

insert into ingrediente_receita VALUES(1,1,1);
insert into ingrediente_receita VALUES(1,1,3);

I did not create a relationship because it is just to refer the fields to the query field to be clear, so follow the query:

SELECT
    r.id,
    r.preparo,
    r.categoria,
    GROUP_CONCAT(i.nome SEPARATOR ' | ') AS ingrediente
FROM receita r
INNER JOIN ingrediente_receita ir
ON ir.id_receita = r.id
INNER JOIN ingrediente i
ON i.id = ir.id_ingrediente
WHERE r.id IN(
SELECT
    r.id
FROM receita r
INNER JOIN ingrediente_receita ir
ON ir.id_receita = r.id
INNER JOIN ingrediente i
ON i.id = ir.id_ingrediente
WHERE ir.id_ingrediente IN(1,3)[id_ingredientes]
HAVING (SELECT COUNT(*) FROM ingrediente_receita WHERE id_receita = r.id) = 2[qtd_ingredientes])

In the [id_identifier] parameter we will pass the id's separated by ',', and in the parameter [qtd_ingredientes] we will pass the amount of ingredients.

The return of the query with the above parameters will be this:

Then for future tests you can go changing the id's and the quantities, for example IN (1,2) as long as he finds the flour will not return because we are looking for some recipe that has 2 ingredients [qtd_ingredientes] and in that return it would bring only 1 line representing the flour.

    
24.11.2017 / 18:32
0

Let's assume you've already done your search and given a fetch array on it, getting the result:

1 | Carrot cake | preparation mode: blablabla | Category: Sweets | flour

1 | Carrot cake | preparation mode: blablabla | Category: Sweets | egg

1 | Carrot cake | preparation mode: blablabla | Category: Sweets | sugar

$rs = [
   0 => [
      'id' => '1',
      'receita' => 'bolo de cenoura',
      'modo' => 'bla bla bla',
      'categoria' => 'doces',
      'ingrediente' => 'farinha'
   ],
   1 => [
      'id' => '2',
      'receita' => 'bolo de cenoura',
      'modo' => 'bla bla bla',
      'categoria' => 'doces',
      'ingrediente' => 'açucar'
   ],
   2 => [
      'id' => '3',
      'receita' => 'bolo de cenoura',
      'modo' => 'bla bla bla',
      'categoria' => 'doces',
      'ingrediente' => 'ovo'
   ]
]

What you will do is to select a column in 'ingredientes' , and implode the data from that array to string :

$ingredientes = array_column($rs, 'ingrediente');
$lista_ingredientes = implode(',', $ingredientes);
echo $lista_ingredientes; //farinha,açucar,ovo

Functional example on Ideone

    
24.11.2017 / 18:04