Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Guariento

Resultar SELECT de um "array" em varchar

Recommended Posts

Estive pesquisando uma solução para a seguinte situação e até agora não encontrei. Vou exemplificar para melhor entenderem:

 

INSERT INTO produto_tag (produto_id, tag) VALUES (1, 'tag1, tag2, tag3') (2, 'tag4, tag5, tag6') (3, 'tag7, tag8, tag9')

 

Isto resulta uma tabela com 3 registros:

 

===========+=================
PRODUTO_ID | TAG
===========+=================
1          | tag1, tag2, tag3
2          | tag4, tag5, tag6
3          | tag7, tag8, tag9

 

Agora, como faço um SELECT que me resulte no seguinte:

 

===========+==================
PRODUTO_ID | TAG_PERSONALIZADA
===========+==================
1          | tag1
1          | tag2
1          | tag3
2          | tag4
2          | tag5
2          | tag6
3          | tag7
3          | tag8
3          | tag9

 

* sabe-se apenas que PRODUTO_ID é tipo INT e TAG é tipo VARCHAR

Compartilhar este post


Link para o post
Compartilhar em outros sites

Vai ser sempre "tag" alguma coisa? Porque se for uma string fixa você pode tentar uma função com um parâmetro pra separar o "array". Ainda assim é um pouco complicado, mas creio que dê de fazer. Contanto que esse "array" não tenha nomes variados.

 

Ou, você pode fazer uma tabela da maneira como colocou ali. O ID se repetindo com a descrição diferente. Seria uma chave composta. Se puder postar o contexto do que você precisa podemos pensar numa solução diferente.

 

--------------------------------

 

Olha, levando em consideração o que eu falei ali em cima eu fiz essa procedure:

 

-- O parâmetro tagx é apenas para contagem de tamanho. No seu caso, você pode passar qualquer string que tenha o mesmo 
-- tamanho do que você quer buscar. Pode passar 'xxxx', 'yyyy', 'tagx', 'tag1', etc, pois não será usado pra comparação
CREATE PROCEDURE `ProdutoId`(tagx varchar(255))
BEGIN
    DECLARE j integer DEFAULT 0;
    DECLARE aux varchar(255); -- Esta variável vai receber o que vamos cortar depois de buscar
    DECLARE len integer DEFAULT LENGTH(tagx); -- Como eu disse, armazenamos o tamanho do parâmetro que você buscou
    DECLARE auxlen integer DEFAULT 1;
    DECLARE id integer(11);
    DECLARE col varchar(255);
    DECLARE cur_tag CURSOR FOR SELECT tag FROM produto_tag; -- CURSOR para armazenarmos as tags buscadas na tabela
    DECLARE cur_id  CURSOR FOR SELECT Produto_id FROM produto_tag; -- CURSOR para armazenarmos os IDs buscados
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET j = 1; -- Assim que não houverem mais resultados na busca o REPEAT acaba, pois setamos j = 1

    OPEN cur_tag;     
    OPEN cur_id;
    DROP TABLE IF EXISTS bd_testes.cur_teste; -- Vamos usar uma tabela temporária dentro da procedure
    CREATE TABLE bd_testes.cur_teste (id integer(11), tag varchar(255));

    REPEAT
         FETCH cur_tag INTO col; -- Pegamos a coluna tag que está na busca
         FETCH cur_id INTO id; -- O ID da mesma
         SET auxlen = 1; -- Trazemos a variável auxlen para 1 toda vez que o REPEAT se iniciar

         -- Vamos executar um WHILE enquanto tivermos o que dividir na coluna que buscamos acima
         WHILE (auxlen < LENGTH(col)) DO
             SET aux = Mid(col,auxlen,len); -- Usamos a função MID para dividir a string 'col', que contém todas aquelas tags em 'array'. Dividimos ela se acordo com o tamanho do parâmetro que foi passado
             IF NOT EXISTS (SELECT 1 FROM cur_teste WHERE tag = aux) THEN INSERT INTO cur_teste VALUES (id,aux); END IF; -- Coloquei este IF pois estava duplicando as informações no final, na última linha da busca.
             SET auxlen = auxlen + len + 2; -- Vamos adicionar ao 'auxlen' o tamanho do parâmetro para que possamos buscar a próxima tag no 'array', e +2, para pular a vírgula e o espaço entre eles
         END WHILE;
    UNTIL (j = 1) END REPEAT;

    SELECT * FROM cur_teste; -- Vamos buscar tudo que adicionamos, esse será o retornor da PROCEDURE

    CLOSE cur_tag;          
    CLOSE cur_id;
    DROP TABLE bd_testes.cur_teste; -- Apagamos a tabela que criamos no início
END;

Faça um teste assim:

 

CALL ProdutoId('tagx');

Fiz baseado nos dados que você passou e funcionou Ok aqui, qualquer dúvida ou modificação que precise ser feita posta aí, estou a disposição =]

 

ABrass.

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.