Why does inner join return repeated values?

0

Good evening,

I have a query to two tables in which I want the second table to return all the data with the id of table 1 but only returns me a table value when there are more than one with the same id. I need to return the data all of the table settings and that returns me the data that is associated with the id of the establishment of the table settings.

Code

if($_REQUEST['valida'] != "ok"){
    if($result_alterar = $conexao->prepare("SELECT * FROM estabelecimentos 
                                            INNER JOIN categorias_estabelecimentos ON categorias_estabelecimentos.estabelecimento_id = estabelecimentos.id
                                            WHERE estabelecimentos.id = :id ")){
        $result_alterar->bindValue(':id', $_POST['id'], PDO::PARAM_INT);
        $result_alterar->execute();
        if($result_alterar->rowCount() >0 ){
            $row_alterar = $result_alterar->fetchAll(PDO::FETCH_ASSOC);
            $_REQUEST = $row_alterar; // O REQUEST ASSUME OS VALORES DO REGISTO, ASSIM EVITAMOS TER QUE CRIAR UM FORMULÁRIO INDEPENDENTE PARA AS EDIÇÕES

        }
    }
}

Table categories_establishments

CREATE TABLE IF NOT EXISTS 'categorias_estabelecimentos' (
'id' int(11) NOT NULL AUTO_INCREMENT,
'estabelecimento_id' int(11) NOT NULL,
'categoria_slug' varchar(250) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY ('id')
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=311 ;

Establishments table

 CREATE TABLE IF NOT EXISTS 'estabelecimentos' (
  'id' int(11) NOT NULL AUTO_INCREMENT,
  'titulo' varchar(250) COLLATE utf8_unicode_ci NOT NULL,
  'slug' varchar(500) COLLATE utf8_unicode_ci NOT NULL,
  'link_facebook' varchar(250) COLLATE utf8_unicode_ci NOT NULL,
  'link_mapa' text COLLATE utf8_unicode_ci NOT NULL,
  'distritos' varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  'concelhos' varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  'morada' varchar(250) COLLATE utf8_unicode_ci NOT NULL,
  'contacto' varchar(250) COLLATE utf8_unicode_ci NOT NULL,
  'int_preco' varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  'link_site' varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  'introducao' text COLLATE utf8_unicode_ci NOT NULL,
  'servicos' varchar(500) COLLATE utf8_unicode_ci NOT NULL,
  'descricao' varchar(500) COLLATE utf8_unicode_ci NOT NULL,
  'keywords' varchar(500) COLLATE utf8_unicode_ci NOT NULL,
  'keywords_pesquisa' varchar(500) COLLATE utf8_unicode_ci NOT NULL,
  'google_verification' varchar(500) COLLATE utf8_unicode_ci NOT NULL,
  'activo' tinyint(1) NOT NULL,
  'pos' bigint(20) NOT NULL,
  PRIMARY KEY ('id')
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=211 ;

Var Dump of variable $ _REQUEST

link

    
asked by anonymous 30.03.2015 / 22:54

1 answer

1

Are not you just picking up the first line?

$row_alterar = $result_alterar->fetch(PDO::FETCH_ASSOC);

What happens if you tell it to return ALL of the lines (an Array will come in case):

$row_alterar = $result_alterar->fetchAll(PDO::FETCH_ASSOC);

This returns all values, the problem is that it may not solve your usage (I understand you have a form involved).

In this case I imagine that the solution would be more in the line of tying an array with the categories to the only establishment. Correct?

Code hint:

if($_REQUEST['valida'] != "ok"){
    if($result_alterar = $conexao->prepare("SELECT * FROM estabelecimentos WHERE estabelecimentos.id = :id ")){
        $result_alterar->bindValue(':id', $_POST['id'], PDO::PARAM_INT);
        $result_alterar->execute();
        if($result_alterar->rowCount() >0 ){
            $row_alterar = $result_alterar->fetch(PDO::FETCH_ASSOC);

            // Puxamos as categorias relevantes para esse estabelecimento
            $result_categorias = $conexao->prepare("SELECT * FROM categorias_estabelecimentos WHERE estabelecimento_id = :id ")
            $result_categorias->bindValue(':id', $_POST['id'], PDO::PARAM_INT);
            $result_categorias->execute();

            // Colocamos a listagem com as categorias como um elemento do estabelecimento
            // Esse é um exemplo que não foi testado, não manjo tanto do seu ORM.
            $row_alterar['categorias_estabelecimentos'] = $result_categorias->fetchAll(PDO::FETCH_ASSOC);

            // Agora basicamente você tem um campo "categorias_estabelecimentos" que vai ter a listagem de categorias, em um único resultado com o estabelecimento que você precisa trabalhar.

            $_REQUEST = $row_alterar; // O REQUEST ASSUME OS VALORES DO REGISTO, ASSIM EVITAMOS TER QUE CRIAR UM FORMULÁRIO INDEPENDENTE PARA AS EDIÇÕES

        }
    }
}

Suggestion to print checkboxes (Not completely related but may be useful):

<?php foreach ($categorias_estabelecimentos as $cat) { ?>
    <input type="hidden" name="categorias_estabelecimentos[<?= $cat['id'] ?>]" value="0" />
    <input type="checkbox" name="categorias_estabelecimentos[<?= $cat['id'] ?>]" value="1" /> <?= $cat['categoria_slug'] ?>
<?php } ?>

The hidden is to, in the post, have the information that something has been cleared. It is the default used by frameworks such as Rails and Angular. The suggestion is partially unrelated but I find it relevant because it treats the peculiarities of dealing with arrays in editing screens, which is relevant to the issue at hand.

    
30.03.2015 / 23:25