none
Consulta utilizando o LIKE de forma muito especifica RRS feed

  • Pergunta

  • Prezados bom dia.

    Estou precisando fazer uma consulta especifica utilizando o LIKE.

    string para consultar: OPTI OU OPTII OU OPTIV

    preciso buscar exatamente a informação OPTI, se eu utilizar "%OPTI%" ele trará as 3. Não posso fazer "gambi" e usar "%OPTI %" (com espaço), pois não sei se ela está no começo, meio ou fim da string.

    Para piorar não estou utilizando exatamente a palavra OPTI e sim um campo de uma tabela:

    ...

    FROM tabela1 T1

    LEFT JOIN tabela T

    ON t1.formula LIKE '%' + T.campo_a_ser_buscado + '%'

    ...

    Já tentei usar o CONTAINS e o FREETEXT mas eles não obedecem o JOIN e muito menos o ALIAS das tabelas.....

    Alguém me salva!!!!

    quinta-feira, 5 de abril de 2012 12:06

Respostas

  • Boa tarde Rodrigo,

    Olha não sei se foi do melhor jeito, mais tentei fazer um esquema para chagar no que você precisa através de um select.

    Deve até haver um jeito mais facil mais segue abaixo um script para ver se te ajuda.

    --Disciplina
    DECLARE @disciplina TABLE
    (
    	disciplina  VARCHAR(15),
    	equivalente	VARCHAR(150)
    )
    
    --Grade do aluno
    DECLARE @grade TABLE
    (
    	grade		INT,
    	disciplina	VARCHAR(15)
    )
    
    --Historico do aluno
    DECLARE @historico TABLE
    (
    	aluno		INT,
    	grade		INT,
    	disciplina	VARCHAR(15),
    	nota		DECIMAL(4,2)
    )
    
    
    --Inclusão das disciplinas e suas equivalentes
    INSERT INTO @disciplina VALUES ('15OPR','EOPR OU XOPR OU HOPR');
    INSERT INTO @disciplina VALUES ('2_DCIV','2DCIV OU IIDCIV OU 23DCIV');
    INSERT INTO @disciplina VALUES ('3_DCIV','3DCIV OU IIIDCIV OU 32DCIV');
    
    --Inclusão de disciplinas na grade do aluno
    INSERT INTO @grade VALUES (1,'15OPR');
    INSERT INTO @grade VALUES (1,'2_DCIV');
    INSERT INTO @grade VALUES (1,'3_DCIV');
    
    --Inclusão no histórico do aluno
    --Veja que a disciplina 3DCIV não está na grade do aluno, mas é equivalente a 3_DCIV da grade
    INSERT INTO @historico VALUES (10,1,'15OPR',7.5);
    INSERT INTO @historico VALUES (10,1,'2_DCIV',5.5);
    INSERT INTO @historico VALUES (10,1,'3DCIV',8.5);
    
    -- CTE EQUIVALENTE
    WITH CTE_EQUIVALENTE AS(
    select SUBSTRING(equivalente,1,CHARINDEX(' ',equivalente,1) - 1) AS EQUIVALENTE_1,
    	   --
    	   SUBSTRING(equivalente,
    				 CHARINDEX(' ',equivalente,CHARINDEX(' ',equivalente,1)+1),
    	   CHARINDEX(' ',equivalente,CHARINDEX(' ',equivalente,1)+CHARINDEX(' ',equivalente,1)) - CHARINDEX(' ',equivalente,CHARINDEX(' ',equivalente,1)+1) - 1) AS EQUIVALENTE_2,	   	 	   
    	   --
    	   SUBSTRING(equivalente,
    				--CHARINDEX(' ',equivalente,CHARINDEX(' ',equivalente,1)+1),
    				CHARINDEX(' ',EQUIVALENTE,CHARINDEX(' ',EQUIVALENTE,CHARINDEX(' ',EQUIVALENTE,CHARINDEX(' ',equivalente,1)+1)+1)+1)+1,
    				LEN(equivalente) - CHARINDEX(' ',EQUIVALENTE,CHARINDEX(' ',EQUIVALENTE,CHARINDEX(' ',EQUIVALENTE,CHARINDEX(' ',equivalente,1)+1)+1)+1) ) AS EQUIVALENTE_3,
    
    	   EQUIVALENTE,
    	   DISCIPLINA				
    from @disciplina)
    
    -- SELECT
    SELECT
    	*
    FROM @grade G
    INNER JOIN CTE_EQUIVALENTE D
    	ON D.disciplina=G.disciplina
    LEFT JOIN @historico H
    	ON H.grade=G.grade	AND (H.disciplina=G.disciplina
    		OR D.equivalente_1 = H.disciplina 
    		OR D.equivalente_2 = H.disciplina 
    		OR D.equivalente_3 = H.disciplina  )

    Att,

    Adriano

    • Marcado como Resposta Rodrigo Escobar segunda-feira, 9 de abril de 2012 17:32
    segunda-feira, 9 de abril de 2012 15:01

Todas as Respostas

  • Olá Rodrigo,

    Sua tabela possui um indice full text? Caso não tenham os predicados CONTAINS e FREETEXT não funcionarão.

    Se quiser usar o like, tente o seguinte comando:

    SELECT * FROM TESTE_a WHERE NOME LIKE '%[ ]OPTI[ ]%'

    Assim, ele vai procurar a paravra OPTI que esteja entre espaços em branco, e não no meio das palavras. Por favor, não esqueça que o desempenho do comando LIKE é extremamente pobre. Faça o possivel para evita-lo

    Abraços.

    Se útil, Classifique.


    Dhiego Piroto - MCP | MCTS SQL Server 2008 Developer | Email: dhiegopiroto@gmail.com

    quinta-feira, 5 de abril de 2012 13:06
  • O Dhiego obrigado pela resposta.

    Eu criei os índices sim, o problema é que não estou digitando o valor na consulta e sim concatenando o campo de uma tabela através de JOINS, veja:

    FROM LY_GRADE AS G
    INNER JOIN LY_ALUNO A 
      ON A.CURSO=G.CURSO
      AND A.CURRICULO=G.CURRICULO
      AND A.TURNO=G.TURNO
    INNER JOIN LY_DISCIPLINA D
      ON D.DISCIPLINA=G.DISCIPLINA
    INNER JOIN LY_HISTMATRICULA H
      ON H.ALUNO=A.ALUNO
      AND (
        H.DISCIPLINA=G.DISCIPLINA
        OR FREETEXT(D.FORMULA_EQUIV,H.disciplina) <--------tentei com o CONTAINS tbm
      )


    Neste momento o SQL retorna o erro:

    Mensagem 102, Nível 15, Estado 1, Linha 27
    Incorrect syntax near 'H'.

    Ou seja, pelo que eu entendi não consigo utilizar desta forma. Ele não reconhece o alias, tentei também trocar o H por ly_histdisciplina (nome da tabela) mas nada adiantou.

    Por isso que pensei no LIKE, mas mesmo assim a resposta sua não funcionou. Veja minha tabela

    Disciplina-->Formula_equiv

    942PRPT --> 952OPTAIII OU 952PRPT
    952OPTAII --> 952PRPTRI
    952OPTAIII --> 942PRPT OU 952PRPT

    select

     disciplina, formula_equiv
    from ly_disciplina
    where formula_equiv like '%[]952PRPT[]%'


    No exemplo a minha disciplina equivalente está no final da primeira e terceira linha, e o select não trouxe nada. Pode haver situações onde ela vem no inicio ou fim....

    Putz, tá triste resolver este problema.

    Abraço.


    quinta-feira, 5 de abril de 2012 13:31
  • Rodrigo,

    Ao invés de usar o JOIN no último caso, use o CROSS APPLY em forma de subquery co-relata.

    Vou dar um exemplo do uso do cross apply( não atente para as tabelas, foi o que consegui bolar agora ).

    DECLARE @TABELA VARCHAR(20) = 'TABELA', @DB VARCHAR(20) = 'TESTE'
    
    SELECT  NOME_CHAVE,TIPO_CHAVE,TABELA,COLUNA_INDEX,	PS.AVG_FRAGMENTATION_IN_PERCENT,
    	PS.AVG_FRAGMENT_SIZE_IN_PAGES,
    	PS.PAGE_COUNT,DB_NAME(PS.DATABASE_ID) AS DB_NAME  FROM
    (SELECT		
    	I.name AS NOME_CHAVE,
    	I.type_desc AS TIPO_CHAVE,
    	OBJECT_NAME(I.object_id) AS TABELA,
    	C.name AS COLUNA_INDEX
    FROM SYS.INDEXES I
    INNER JOIN SYS.index_columns IC ON I.object_id = IC.object_id AND I.index_id = IC.index_id
    	INNER JOIN SYS.COLUMNS C ON IC.column_id = C.column_id AND IC.object_id = C.object_id
    WHERE I.OBJECT_ID = OBJECT_ID(@TABELA))AS PRINC
    CROSS APPLY syS.dm_db_index_physical_stats (DB_ID(@DB),OBJECT_ID(@TABELA),NULL,NULL,NULL) PS
    			WHERE PS.OBJECT_ID = OBJECT_ID(@TABELA)

    Abraços


    Dhiego Piroto - MCP | MCTS SQL Server 2008 Developer | Email: dhiegopiroto@gmail.com

    quinta-feira, 5 de abril de 2012 13:39
  • Dhiego,

    Pensei em um primeiro momento em CROSSAPLY, mas nesta base minha ele não está funcionando. Não sei se é porque está funcionando em modo de compatibilidade ou não. Ela foi "importada" do banco SQL Server 2000...

    Mas acho que eu continuaria com o mesmo problema, pois o item que quero está em um campo tipo VARCHAR que em alguns casos possui 250 caracteres baseado em formulas como esta:  942PRPT OU 952PRPT OU FRDCV OU IPDVB

    Mas mesmo assim obrigado pela ajuda

    quinta-feira, 5 de abril de 2012 13:47
  • Bom dia Rodrigo,

    Não sei se entendi o que você precisa, mais tentei montar um exemplo conforme os scripts abaixo com o like.

    Veja se o exemplo abaixo retorna o que você precisa( no exemplo me referenciei no seu 1º exemplo ).

    Qualquer dúvida ou problema notifique.

    -- TABELA
    DECLARE @TABLE AS TABLE(
    COLUNA	VARCHAR(10)
    )
    
    DECLARE @TABLE2 AS TABLE(
    COLUNA2 VARCHAR(10)
    )
    
    -- INFORMAÇÕES
    INSERT INTO @TABLE VALUES('OPTI');
    INSERT INTO @TABLE VALUES('OPTII');
    INSERT INTO @TABLE VALUES('OPTIV');
    INSERT INTO @TABLE VALUES('ABCOPTIDEF');
    INSERT INTO @TABLE VALUES('123OPTI456');
    
    INSERT INTO @TABLE2 VALUES('OPTI');
    INSERT INTO @TABLE2 VALUES('TESTE');
    
    -- SEELECT 1
    SELECT * FROM @TABLE WHERE COLUNA LIKE('%OPTI%') 
    					 AND COLUNA NOT LIKE('%OPTII%') 
    				     AND COLUNA NOT LIKE('%OPTIV%');
    
    
    -- SEELECT 2
    SELECT * FROM @TABLE A INNER JOIN @TABLE2 B ON A.COLUNA LIKE '%' + B.COLUNA2 + '%' 
    WHERE A.COLUNA NOT LIKE '%' + B.COLUNA2 + 'I%'
    AND   A.COLUNA NOT LIKE '%' + B.COLUNA2 + 'V%'

    Abçs,

    Adriano

    quinta-feira, 5 de abril de 2012 14:23
  • Bom dia Rodrigo,

    Não sei se entendi o que você precisa, mais tentei montar um exemplo conforme os scripts abaixo com o like.

    Veja se o exemplo abaixo retorna o que você precisa( no exemplo me referenciei no seu 1º exemplo ).

    Qualquer dúvida ou problema notifique.

    -- TABELA
    DECLARE @TABLE AS TABLE(
    COLUNA	VARCHAR(10)
    )
    
    DECLARE @TABLE2 AS TABLE(
    COLUNA2 VARCHAR(10)
    )
    
    -- INFORMAÇÕES
    INSERT INTO @TABLE VALUES('OPTI');
    INSERT INTO @TABLE VALUES('OPTII');
    INSERT INTO @TABLE VALUES('OPTIV');
    INSERT INTO @TABLE VALUES('ABCOPTIDEF');
    INSERT INTO @TABLE VALUES('123OPTI456');
    
    INSERT INTO @TABLE2 VALUES('OPTI');
    INSERT INTO @TABLE2 VALUES('TESTE');
    
    -- SEELECT 1
    SELECT * FROM @TABLE WHERE COLUNA LIKE('%OPTI%') 
    					 AND COLUNA NOT LIKE('%OPTII%') 
    				     AND COLUNA NOT LIKE('%OPTIV%');
    
    
    -- SEELECT 2
    SELECT * FROM @TABLE A INNER JOIN @TABLE2 B ON A.COLUNA LIKE '%' + B.COLUNA2 + '%' 
    WHERE A.COLUNA NOT LIKE '%' + B.COLUNA2 + 'I%'
    AND   A.COLUNA NOT LIKE '%' + B.COLUNA2 + 'V%'

    Abçs,

    Adriano

    Adriano

    Obrigado pela resposta mas não posso fazer desta forma, pois em minha base mais de 1000 disciplinas e os nomes são bem variados. Ou seja em um determinado momento pode vir uma que não tenha o I ou V e a clausula não funcionará.

    At+

    quinta-feira, 5 de abril de 2012 14:29
  • Boa tarde Rodrigo,

    Estou com algumas dúvidas neste caso.

    O like que você esta tentando utilizar é para localizar apenas uma disciplina?

    outro ponto é, no campo que você esta pesquisando a disciplina esta apenas a informação da dispociplina ?

    Pergunto pois entendo que para disciplina você deve ter um código ou um nome único, ai ficaria mais facil de pesquisar por este campo, se não tive este campo poderia ser pensado em criar o mesmo.

    Abçs,

    Adriano Nascimento

    quinta-feira, 5 de abril de 2012 15:36
  • Boa tarde Rodrigo,

    Estou com algumas dúvidas neste caso.

    O like que você esta tentando utilizar é para localizar apenas uma disciplina?

    outro ponto é, no campo que você esta pesquisando a disciplina esta apenas a informação da dispociplina ?

    Pergunto pois entendo que para disciplina você deve ter um código ou um nome único, ai ficaria mais facil de pesquisar por este campo, se não tive este campo poderia ser pensado em criar o mesmo.

    Abçs,

    Adriano Nascimento

    Bom dia Adriano,

    Desculpe a demora na resposta. Espero que ainda esteja disposto a me ajudar.

    Sim estou utilizando o LIKE para achar uma disciplina. Realmente o código da disciplina é único em minha tabela, mas estou pesquisando este código em um campo chamado equivalência, e este campo possui várias disciplinas criando assim uma fórmula ex: "EOPR OU XOPR OU HOPR E (ROPD OU IORP)".

    Fiz a simulação de minha informação para você ver o que tenho e ver o meu problema:

    --Disciplina DECLARE @disciplina TABLE ( disciplina VARCHAR(15), equivalente VARCHAR(150) ) --Grade do aluno DECLARE @grade TABLE ( grade INT, disciplina VARCHAR(15) ) --Historico do aluno DECLARE @historico TABLE ( aluno INT, grade INT, disciplina VARCHAR(15), nota DECIMAL(4,2) ) --Inclusão das disciplinas e suas equivalentes INSERT INTO @disciplina VALUES ('15OPR','EOPR OU XOPR OU HOPR'); INSERT INTO @disciplina VALUES ('2_DCIV','2DCIV OU IIDCIV OU 23DCIV'); INSERT INTO @disciplina VALUES ('3_DCIV','3DCIV OU IIIDCIV OU 32DCIV'); --Inclusão de disciplinas na grade do aluno INSERT INTO @grade VALUES (1,'15OPR'); INSERT INTO @grade VALUES (1,'2_DCIV'); INSERT INTO @grade VALUES (1,'3_DCIV'); --Inclusão no histórico do aluno --Veja que a disciplina 3DCIV não está na grade do aluno, mas é equivalente a 3_DCIV da grade INSERT INTO @historico VALUES (10,1,'15OPR',7.5); INSERT INTO @historico VALUES (10,1,'2_DCIV',5.5); INSERT INTO @historico VALUES (10,1,'3DCIV',8.5); SELECT * FROM @grade G INNER JOIN @disciplina D ON D.disciplina=G.disciplina LEFT JOIN @historico H ON H.grade=G.grade

    AND (

    H.disciplina=G.disciplina OR D.equivalente LIKE '%' + H.disciplina + '%' )


    Entenda que:

    1 Aluno possui uma grade (grade do curso)

    A grade possui as disciplinas que ele deve cursar.

    No histórico contém as disciplinas que ele realmente cursou.

    Se você verificar, meu aluno cursou a disciplina 3DCIV que é equivalente a disciplina 3_DCIV da grade curricular dele. 

    Então penso o seguinte:

    Se eu não achar a disciplina da grade no histórico

    LEFT JOIN @historico H ON H.grade=G.grade

    AND ( H.disciplina=G.disciplina

    Devo então ir na formula de equivalencia da disciplina curricular e verificar se a que ele fez está lá.

    OR D.equivalente LIKE '%' + H.disciplina + '%'

    problema:

    Na disciplina 2_DCIV existe uma disciplina na formula que se chama 23DCIV, e por causa disso o LIKE trás a 2_DCIV duas vezes por causa da disciplina 3DCIV.

    Por isso eu preciso fazer uma consulta no LIKE buscando exatamente a palavra 3DCIV.

    Desde já agradeço.

    segunda-feira, 9 de abril de 2012 11:30
  • Bom dia Rodrigo,

    Então, pelo que entendi, a principio a minha idéia seria quebrar o campo equivalente da tabela disciplina em coidgos de equivalente únicos.

    veja o meu exemplo abaixo ( fiz as alterações no seu exemplo ).

    Qualquer problema posta ai.

    --Disciplina
    DECLARE @disciplina TABLE
    (
    	disciplina  VARCHAR(15),
    	equivalente_1	VARCHAR(15),
    	equivalente_2	VARCHAR(15),
    	equivalente_3	VARCHAR(15)
    )
    
    --Grade do aluno
    DECLARE @grade TABLE
    (
    	grade		INT,
    	disciplina	VARCHAR(15)
    )
    
    --Historico do aluno
    DECLARE @historico TABLE
    (
    	aluno		INT,
    	grade		INT,
    	disciplina	VARCHAR(15),
    	nota		DECIMAL(4,2)
    )
    
    
    --Inclusão das disciplinas e suas equivalentes
    INSERT INTO @disciplina VALUES ('15OPR','EOPR','XOPR','HOPR');
    INSERT INTO @disciplina VALUES ('2_DCIV','2DCIV','IIDCIV','23DCIV');
    INSERT INTO @disciplina VALUES ('3_DCIV','3DCIV','IIIDCIV','32DCIV');
    
    --Inclusão de disciplinas na grade do aluno
    INSERT INTO @grade VALUES (1,'15OPR');
    INSERT INTO @grade VALUES (1,'2_DCIV');
    INSERT INTO @grade VALUES (1,'3_DCIV');
    
    --Inclusão no histórico do aluno
    --Veja que a disciplina 3DCIV não está na grade do aluno, mas é equivalente a 3_DCIV da grade
    INSERT INTO @historico VALUES (10,1,'15OPR',7.5);
    INSERT INTO @historico VALUES (10,1,'2_DCIV',5.5);
    INSERT INTO @historico VALUES (10,1,'3DCIV',8.5);
    
    
    SELECT
    	*
    FROM @grade G
    INNER JOIN @disciplina D
    	ON D.disciplina=G.disciplina
    LEFT JOIN @historico H
    	ON H.grade=G.grade	AND (H.disciplina=G.disciplina
    		OR D.equivalente_1 = H.disciplina 
    		OR D.equivalente_2 = H.disciplina 
    		OR D.equivalente_3 = H.disciplina  )

    Att,

    Adriano

    • Sugerido como Resposta Heloisa Pires segunda-feira, 9 de abril de 2012 14:04
    segunda-feira, 9 de abril de 2012 12:24
  • Adriano bom dia,

    Entendi o que você disse.

    Esta é uma saída que eu não gostaria, pois, não posso alterar minha base de dados (sistema legado) e então eu deveria criar uma função para este tratamento.

    Mas tranquilo, vou para a função mesmo.

    Muito obrigado pela ajuda e atenção.


    .:: Rodrigo Escobar ::.

    segunda-feira, 9 de abril de 2012 13:19
  • Boa tarde Rodrigo,

    Olha não sei se foi do melhor jeito, mais tentei fazer um esquema para chagar no que você precisa através de um select.

    Deve até haver um jeito mais facil mais segue abaixo um script para ver se te ajuda.

    --Disciplina
    DECLARE @disciplina TABLE
    (
    	disciplina  VARCHAR(15),
    	equivalente	VARCHAR(150)
    )
    
    --Grade do aluno
    DECLARE @grade TABLE
    (
    	grade		INT,
    	disciplina	VARCHAR(15)
    )
    
    --Historico do aluno
    DECLARE @historico TABLE
    (
    	aluno		INT,
    	grade		INT,
    	disciplina	VARCHAR(15),
    	nota		DECIMAL(4,2)
    )
    
    
    --Inclusão das disciplinas e suas equivalentes
    INSERT INTO @disciplina VALUES ('15OPR','EOPR OU XOPR OU HOPR');
    INSERT INTO @disciplina VALUES ('2_DCIV','2DCIV OU IIDCIV OU 23DCIV');
    INSERT INTO @disciplina VALUES ('3_DCIV','3DCIV OU IIIDCIV OU 32DCIV');
    
    --Inclusão de disciplinas na grade do aluno
    INSERT INTO @grade VALUES (1,'15OPR');
    INSERT INTO @grade VALUES (1,'2_DCIV');
    INSERT INTO @grade VALUES (1,'3_DCIV');
    
    --Inclusão no histórico do aluno
    --Veja que a disciplina 3DCIV não está na grade do aluno, mas é equivalente a 3_DCIV da grade
    INSERT INTO @historico VALUES (10,1,'15OPR',7.5);
    INSERT INTO @historico VALUES (10,1,'2_DCIV',5.5);
    INSERT INTO @historico VALUES (10,1,'3DCIV',8.5);
    
    -- CTE EQUIVALENTE
    WITH CTE_EQUIVALENTE AS(
    select SUBSTRING(equivalente,1,CHARINDEX(' ',equivalente,1) - 1) AS EQUIVALENTE_1,
    	   --
    	   SUBSTRING(equivalente,
    				 CHARINDEX(' ',equivalente,CHARINDEX(' ',equivalente,1)+1),
    	   CHARINDEX(' ',equivalente,CHARINDEX(' ',equivalente,1)+CHARINDEX(' ',equivalente,1)) - CHARINDEX(' ',equivalente,CHARINDEX(' ',equivalente,1)+1) - 1) AS EQUIVALENTE_2,	   	 	   
    	   --
    	   SUBSTRING(equivalente,
    				--CHARINDEX(' ',equivalente,CHARINDEX(' ',equivalente,1)+1),
    				CHARINDEX(' ',EQUIVALENTE,CHARINDEX(' ',EQUIVALENTE,CHARINDEX(' ',EQUIVALENTE,CHARINDEX(' ',equivalente,1)+1)+1)+1)+1,
    				LEN(equivalente) - CHARINDEX(' ',EQUIVALENTE,CHARINDEX(' ',EQUIVALENTE,CHARINDEX(' ',EQUIVALENTE,CHARINDEX(' ',equivalente,1)+1)+1)+1) ) AS EQUIVALENTE_3,
    
    	   EQUIVALENTE,
    	   DISCIPLINA				
    from @disciplina)
    
    -- SELECT
    SELECT
    	*
    FROM @grade G
    INNER JOIN CTE_EQUIVALENTE D
    	ON D.disciplina=G.disciplina
    LEFT JOIN @historico H
    	ON H.grade=G.grade	AND (H.disciplina=G.disciplina
    		OR D.equivalente_1 = H.disciplina 
    		OR D.equivalente_2 = H.disciplina 
    		OR D.equivalente_3 = H.disciplina  )

    Att,

    Adriano

    • Marcado como Resposta Rodrigo Escobar segunda-feira, 9 de abril de 2012 17:32
    segunda-feira, 9 de abril de 2012 15:01
  • Boa tarde Rodrigo,

    Olha não sei se foi do melhor jeito, mais tentei fazer um esquema para chagar no que você precisa através de um select.

    Deve até haver um jeito mais facil mais segue abaixo um script para ver se te ajuda.

    --Disciplina
    DECLARE @disciplina TABLE
    (
    	disciplina  VARCHAR(15),
    	equivalente	VARCHAR(150)
    )
    
    --Grade do aluno
    DECLARE @grade TABLE
    (
    	grade		INT,
    	disciplina	VARCHAR(15)
    )
    
    --Historico do aluno
    DECLARE @historico TABLE
    (
    	aluno		INT,
    	grade		INT,
    	disciplina	VARCHAR(15),
    	nota		DECIMAL(4,2)
    )
    
    
    --Inclusão das disciplinas e suas equivalentes
    INSERT INTO @disciplina VALUES ('15OPR','EOPR OU XOPR OU HOPR');
    INSERT INTO @disciplina VALUES ('2_DCIV','2DCIV OU IIDCIV OU 23DCIV');
    INSERT INTO @disciplina VALUES ('3_DCIV','3DCIV OU IIIDCIV OU 32DCIV');
    
    --Inclusão de disciplinas na grade do aluno
    INSERT INTO @grade VALUES (1,'15OPR');
    INSERT INTO @grade VALUES (1,'2_DCIV');
    INSERT INTO @grade VALUES (1,'3_DCIV');
    
    --Inclusão no histórico do aluno
    --Veja que a disciplina 3DCIV não está na grade do aluno, mas é equivalente a 3_DCIV da grade
    INSERT INTO @historico VALUES (10,1,'15OPR',7.5);
    INSERT INTO @historico VALUES (10,1,'2_DCIV',5.5);
    INSERT INTO @historico VALUES (10,1,'3DCIV',8.5);
    
    -- CTE EQUIVALENTE
    WITH CTE_EQUIVALENTE AS(
    select SUBSTRING(equivalente,1,CHARINDEX(' ',equivalente,1) - 1) AS EQUIVALENTE_1,
    	   --
    	   SUBSTRING(equivalente,
    				 CHARINDEX(' ',equivalente,CHARINDEX(' ',equivalente,1)+1),
    	   CHARINDEX(' ',equivalente,CHARINDEX(' ',equivalente,1)+CHARINDEX(' ',equivalente,1)) - CHARINDEX(' ',equivalente,CHARINDEX(' ',equivalente,1)+1) - 1) AS EQUIVALENTE_2,	   	 	   
    	   --
    	   SUBSTRING(equivalente,
    				--CHARINDEX(' ',equivalente,CHARINDEX(' ',equivalente,1)+1),
    				CHARINDEX(' ',EQUIVALENTE,CHARINDEX(' ',EQUIVALENTE,CHARINDEX(' ',EQUIVALENTE,CHARINDEX(' ',equivalente,1)+1)+1)+1)+1,
    				LEN(equivalente) - CHARINDEX(' ',EQUIVALENTE,CHARINDEX(' ',EQUIVALENTE,CHARINDEX(' ',EQUIVALENTE,CHARINDEX(' ',equivalente,1)+1)+1)+1) ) AS EQUIVALENTE_3,
    
    	   EQUIVALENTE,
    	   DISCIPLINA				
    from @disciplina)
    
    -- SELECT
    SELECT
    	*
    FROM @grade G
    INNER JOIN CTE_EQUIVALENTE D
    	ON D.disciplina=G.disciplina
    LEFT JOIN @historico H
    	ON H.grade=G.grade	AND (H.disciplina=G.disciplina
    		OR D.equivalente_1 = H.disciplina 
    		OR D.equivalente_2 = H.disciplina 
    		OR D.equivalente_3 = H.disciplina  )

    Att,

    Adriano

    Pô Adriano.... 

    Agora sim!!! Você me deu o norte, só vou acertar para deixar a quantidade de colunas no WITH dinamico....

    Muito obrigado mesmo.

    Abc


    .:: Rodrigo Escobar ::.

    segunda-feira, 9 de abril de 2012 17:32