none
Ultimo Status RRS feed

  • Pergunta

  • Boa Tarde,

    Caros estou com a seguinte duvida....

    Preciso criar uma variavel flag_ultima_pos, tipo ela deve receber 1 na ultima posição de cada...cliente na tabela...por exemplo:

    Cod_Cliente                       Data                        Flg_Ultima_pos
    11                                  01/10/2008                           0
    11                                 
    04/10/2008                           1
    12                                  05/10/2008                           0
    12                                  06/10/2008                           0
    12                                  09/10/2008                           0
    12                                  10/10/2008                           1
    14                                  01/10/2008                           0
    14                                  06/10/2008                           1
    16                                  01/10/2008                           1
    19                                  01/10/2008                           1

    tipo eu queria q esse numera seja ajustavel automaticamente...!!


    att,
    Tiodimi
    segunda-feira, 10 de novembro de 2008 19:09

Respostas

  • Boa Noite,

     

    Há duas formas, uma por view e outra por trigger. Ex:

     

    Code Snippet

    CREATE TABLE CLIENTES (Cod_Cliente INT, Data SMALLDATETIME)

    INSERT INTO CLIENTES VALUES (11,'20081001')

    INSERT INTO CLIENTES VALUES (11,'20081004')

    INSERT INTO CLIENTES VALUES (12,'20081005')

    INSERT INTO CLIENTES VALUES (12,'20081006')

    INSERT INTO CLIENTES VALUES (12,'20081009')

    INSERT INTO CLIENTES VALUES (12,'20081010')

    INSERT INTO CLIENTES VALUES (14,'20081001')

    INSERT INTO CLIENTES VALUES (14,'20081006')

    INSERT INTO CLIENTES VALUES (16,'20081001')

    INSERT INTO CLIENTES VALUES (19,'20081001')

     

    CREATE VIEW vwUltimaPosClientes (Cod_Cliente, Data, Flg_Ultima_Pos)

    AS

    SELECT Cod_Cliente, Data,

    CASE WHEN (

    SELECT MAX(Data) FROM Clientes AS TInt

    WHERE TOut.Cod_Cliente = TInt.Cod_Cliente

    GROUP BY Cod_Cliente

    ) = TOut.Data THEN 1 ELSE 0 END

    AS Flg_Ultima_Pos

    FROM Clientes AS TOut

     

    SELECT Cod_Cliente, Data, Flg_Ultima_Pos FROM vwUltimaPosClientes

     

    Code Snippet

    CREATE TABLE CLIENTES (Cod_Cliente INT, Data SMALLDATETIME, Flg_Ultima_Pos TINYINT DEFAULT 0 NULL)

     

    CREATE TRIGGER trgUltimaPos ON CLIENTES

    FOR INSERT, UPDATE

    AS

    BEGIN

    UPDATE Clientes SET Flg_Ultima_Pos = 0

    WHERE Cod_Cliente IN (SELECT Cod_Cliente FROM INSERTED)

     

    UPDATE Clientes SET Flg_Ultima_Pos = 1

    FROM Clientes INNER JOIN

    (SELECT Cod_Cliente, MAX(Data) As Data FROM Clientes

    GROUP BY Cod_Cliente) AS Q

    ON Clientes.Cod_Cliente = Q.Cod_Cliente AND Clientes.Data = Q.Data

     

    END

     

    INSERT INTO CLIENTES (Cod_Cliente,Data) VALUES (11,'20081001')

    INSERT INTO CLIENTES (Cod_Cliente,Data) VALUES (12,'20081005')

    INSERT INTO CLIENTES (Cod_Cliente,Data) VALUES (12,'20081006')

    INSERT INTO CLIENTES (Cod_Cliente,Data) VALUES (14,'20081001')

    INSERT INTO CLIENTES (Cod_Cliente,Data) VALUES (16,'20081001')

    INSERT INTO CLIENTES (Cod_Cliente,Data) VALUES (19,'20081001')

     

    SELECT Cod_Cliente,Data,Flg_Ultima_Pos FROM Clientes ORDER BY Cod_Cliente

     

    INSERT INTO CLIENTES (Cod_Cliente,Data) VALUES (11,'20081004')

    INSERT INTO CLIENTES (Cod_Cliente,Data) VALUES (12,'20081009')

    INSERT INTO CLIENTES (Cod_Cliente,Data) VALUES (12,'20081010')

    INSERT INTO CLIENTES (Cod_Cliente,Data) VALUES (14,'20081006')

     

    SELECT Cod_Cliente,Data,Flg_Ultima_Pos FROM Clientes ORDER BY Cod_Cliente

     

     

    Se você faz muita escrita e pouca consulta, a view é a melhor solução. Se você faz muita consulta e pouca escrita a trigger e a melhor solução. Se você faz muita escrita e muita consulta e não sabe o que escolher a view tende a ser a melhor solução. Creio que o overhead das triggers seja prejudicial.

     

    [ ]s,

     

    Gustavo

     

    segunda-feira, 10 de novembro de 2008 22:10

Todas as Respostas

  • Boa Noite,

     

    Há duas formas, uma por view e outra por trigger. Ex:

     

    Code Snippet

    CREATE TABLE CLIENTES (Cod_Cliente INT, Data SMALLDATETIME)

    INSERT INTO CLIENTES VALUES (11,'20081001')

    INSERT INTO CLIENTES VALUES (11,'20081004')

    INSERT INTO CLIENTES VALUES (12,'20081005')

    INSERT INTO CLIENTES VALUES (12,'20081006')

    INSERT INTO CLIENTES VALUES (12,'20081009')

    INSERT INTO CLIENTES VALUES (12,'20081010')

    INSERT INTO CLIENTES VALUES (14,'20081001')

    INSERT INTO CLIENTES VALUES (14,'20081006')

    INSERT INTO CLIENTES VALUES (16,'20081001')

    INSERT INTO CLIENTES VALUES (19,'20081001')

     

    CREATE VIEW vwUltimaPosClientes (Cod_Cliente, Data, Flg_Ultima_Pos)

    AS

    SELECT Cod_Cliente, Data,

    CASE WHEN (

    SELECT MAX(Data) FROM Clientes AS TInt

    WHERE TOut.Cod_Cliente = TInt.Cod_Cliente

    GROUP BY Cod_Cliente

    ) = TOut.Data THEN 1 ELSE 0 END

    AS Flg_Ultima_Pos

    FROM Clientes AS TOut

     

    SELECT Cod_Cliente, Data, Flg_Ultima_Pos FROM vwUltimaPosClientes

     

    Code Snippet

    CREATE TABLE CLIENTES (Cod_Cliente INT, Data SMALLDATETIME, Flg_Ultima_Pos TINYINT DEFAULT 0 NULL)

     

    CREATE TRIGGER trgUltimaPos ON CLIENTES

    FOR INSERT, UPDATE

    AS

    BEGIN

    UPDATE Clientes SET Flg_Ultima_Pos = 0

    WHERE Cod_Cliente IN (SELECT Cod_Cliente FROM INSERTED)

     

    UPDATE Clientes SET Flg_Ultima_Pos = 1

    FROM Clientes INNER JOIN

    (SELECT Cod_Cliente, MAX(Data) As Data FROM Clientes

    GROUP BY Cod_Cliente) AS Q

    ON Clientes.Cod_Cliente = Q.Cod_Cliente AND Clientes.Data = Q.Data

     

    END

     

    INSERT INTO CLIENTES (Cod_Cliente,Data) VALUES (11,'20081001')

    INSERT INTO CLIENTES (Cod_Cliente,Data) VALUES (12,'20081005')

    INSERT INTO CLIENTES (Cod_Cliente,Data) VALUES (12,'20081006')

    INSERT INTO CLIENTES (Cod_Cliente,Data) VALUES (14,'20081001')

    INSERT INTO CLIENTES (Cod_Cliente,Data) VALUES (16,'20081001')

    INSERT INTO CLIENTES (Cod_Cliente,Data) VALUES (19,'20081001')

     

    SELECT Cod_Cliente,Data,Flg_Ultima_Pos FROM Clientes ORDER BY Cod_Cliente

     

    INSERT INTO CLIENTES (Cod_Cliente,Data) VALUES (11,'20081004')

    INSERT INTO CLIENTES (Cod_Cliente,Data) VALUES (12,'20081009')

    INSERT INTO CLIENTES (Cod_Cliente,Data) VALUES (12,'20081010')

    INSERT INTO CLIENTES (Cod_Cliente,Data) VALUES (14,'20081006')

     

    SELECT Cod_Cliente,Data,Flg_Ultima_Pos FROM Clientes ORDER BY Cod_Cliente

     

     

    Se você faz muita escrita e pouca consulta, a view é a melhor solução. Se você faz muita consulta e pouca escrita a trigger e a melhor solução. Se você faz muita escrita e muita consulta e não sabe o que escolher a view tende a ser a melhor solução. Creio que o overhead das triggers seja prejudicial.

     

    [ ]s,

     

    Gustavo

     

    segunda-feira, 10 de novembro de 2008 22:10
  • Maia,

     

    Concordo com você ambas são excelentes opção, se o volume for pequeno, acredito que a view poderia ser a solução mais indicada.

    terça-feira, 11 de novembro de 2008 10:31
    Moderador
  • Obrigado pela ajuda...porém...tenho um volume consideravel de informacoes cerca de 20Milhoes...e por exemplo essa Flg tem q ser dinamica pois..um dia em certo cliente X ela vai estar flegada com 1 e outro dia flegada com 0...pois como vamos atualizando ela tem q ver o historico do cliente...

    nao tem como tipo fazer ....

    alter table...

    add flag_ultimo_status as (.........)

    ?!

    Grato,

    Att,
    Tiodimi
    terça-feira, 11 de novembro de 2008 12:33
  • Bom Dia,

     

    Não há como criar uma coluna calculada que utilize uma subquery, ainda que funcionasse isso seria idêntico ao processamento da View. Recomendo seguir as orientações a cerca de leitura e escrita para basear-se em utilizar a view ou não.

     

    20 milhões de registros é um número grande mas não significa um grande volume, é preciso avaliar a largura do registros. 20 milhões de registros em uma tabela com 2 campos INT equivale a uma tabela de 160MB.

     

    [ ]s,

     

    Gustavo

    terça-feira, 11 de novembro de 2008 13:42
  • obrigado pela atenção...

    bom +/- 20M com umas 156 colunas...quase todos os tipo de dados....e esse numero cresce todo o dia....cerca de 200Mil registros.....o problema q os usuario ao qual consulta a tabela utilizam um sft ao qual nao vizualiza uma View....por isso "essa flag deve ser criada na tabela..."


    grato,....


    Att,
    Tiodimi



    terça-feira, 11 de novembro de 2008 14:02
  • Olá Tiodimi,

     

    Normalmente uma tabela com 156 colunas denota erros de modelagem de dados. Considerando que o SQL Server suporta no máximo 8K por registro (desconsiderando tipos BLOBs) você pode inclusive estar com a possibilidade de ter dados truncados. Em todo caso isso é assunto para uma outra dúvida.

     

    Se o software é tão inflexível para não poder usar a View ele será capaz de enxergar a flag ? Se essa é uma imposição, você terá que optar pela trigger, já que a View não atenderá essa limitação.

     

    [ ]s,

     

    Gustavo

    terça-feira, 11 de novembro de 2008 15:29
  • esse numero é tão grande devido ao numero de informações necessarias..que usamos...acredite é pouco....

    bom a flg...vai estar na tabela sendo assim...é possivel..q ele enxergue....enfim...tentarei com trigger...

    Obrigado pela anteção...


    Att,
    Tiodimi
    terça-feira, 11 de novembro de 2008 15:35
  • Ok Tiodimi,

     

    Espero que a trigger o atenda.

     

    [ ]s,

     

    Gustavo

    terça-feira, 11 de novembro de 2008 18:11
  • Muito obrigado Gustavo e Junior!
    terça-feira, 11 de novembro de 2008 18:20