AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 251778
Accepted
FallenAngel
FallenAngel
Asked: 2019-10-24 03:40:46 +0800 CST2019-10-24 03:40:46 +0800 CST 2019-10-24 03:40:46 +0800 CST

Criar sequência com base no valor de outra coluna

  • 772

Eu tenho que criar números de sequência com base no usuário relacionado. Curti:

╔════════════╦═════════════╦═══════════════════╗
║ Row Id     ║ User Id     ║ Sequence Number   ║
╠════════════╬═════════════╬═══════════════════╣
║ 1          ║ 1           ║         1         ║
║ 2          ║ 1           ║         2         ║
║ 3          ║ 2           ║         1         ║
║ 4          ║ 2           ║         2         ║
║ 5          ║ 3           ║         1         ║
║ 6          ║ 1           ║         3         ║
╚════════════╩═════════════╩═══════════════════╝

Tenho alguns pré-requisitos:

  • Cada número de seqüência deve estar entre 1 e 9999. Após 9999, deve saltar para 1 e continuar a partir daí. (propriedade CICLO da Sequência)
  • Os números de sequência devem ser gerados com base no ID do usuário. Cada UserId deve ter sua própria sequência.
  • Os números de sequência devem ser sequenciais. tal que para o ID de usuário 5: Sequência # 123 deve ser seguida por 124, salto ou reutilização de um número não deve acontecer.

Então, usar uma sequência parece muito certo para mim. Mas não consegui adicionar distinção de ID de usuário à sequência.

CREATE SEQUENCE [dbo].[seq_SequenceNumber] 
AS [smallint]
START WITH 1
INCREMENT BY 1
MINVALUE 1
MAXVALUE 9999
CYCLE 
NO CACHE  

Como posso adicionar a partição UserId a essa sequência?

sql-server sequence
  • 1 1 respostas
  • 3468 Views

1 respostas

  • Voted
  1. Best Answer
    Michael Green
    2019-10-24T21:57:56+08:002019-10-24T21:57:56+08:00

    Isso produzirá o resultado desejado para uma única consulta.

    drop table if exists T1;
    go
    
    create table T1(RowId int, UserId int, Desired_SequenceNumber int);
    go
    insert T1
    values
    (1, 1, 9997),
    (2, 1, 9998),
    (3, 2, 1),
    (4, 2, 2),
    (5, 3, 1),
    (6, 1, 9999);   -- Have increased User 1's values to test wrap-around.
    go
    
    select
        T1.*,
        SequenceNumber = ((ROW_NUMBER() over (partition by UserId order by RowId) - 1) % 9999) + 1
    from t1
    order by RowId;
    

    A função interna ROW_NUMBER cria um número inteiro sequencial para cada linha no resultado. partition by UserIdgarante que cada valor de UserId comece a contar novamente em 1. Order by RowIdgarante que a ordenação de SequenceNumber corresponda à ordenação de RowId. O - 1) % 9999) + 1bit garante o wrap-around em 9999 e o início novamente em 1, em vez de zero.

    Se os SequenceNumbers devem ser escritos uma vez e consistentes para todas as leituras subsequentes, o acima não funcionará. Então você vai precisar de algo como

    ;with NewData as
    (
        select *
        from
        (
            values
                (7, 1),
                (8, 4)
        ) as T(RowId, UserId)
    ),
    LatestRow as
    (
        select
            UserId,
            RowId = MAX(RowId)
        from T1
        group by UserId
    ),
    NextSequence as
    (
        select
            T1.UserId,
            Number = (T1.Desired_SequenceNumber + 1) % 9999
        from T1
        inner join LatestRow
            on LatestRow.RowId = T1.RowId
    )
    -- insert T1(RowId, UserId, Desired_SequenceNumber)
    select
        NewData.RowId,
        NewData.UserId,
        Desired_SequenceNumber = ISNULL(NextSequence.Number, 1)
    from NewData
    left outer join NextSequence
        on NextSequence.UserId = NewData.UserId;
    

    Eu estruturei usando CTEs para facilitar a exposição. Poderia ser re-fatorado para desempenho.

    CTE NewData introduz dados de teste sem ter que gerenciar tabelas. Substitua isso pela sua fonte real. Observe que RowId 7 é para um usuário existente e 8 é para um novo usuário. Eu codifiquei RowIds para facilitar a referência. Isso não é necessário para esta solução. Suas tabelas provavelmente usam uma IDENTIDADE e tudo bem.

    Porque os números que envolvem a solução devem encontrar o valor mais recente, não o maior valor, e incrementar a partir daí. Eu uso RowId como um proxy para o tempo. O CTE LatestRow encontra o RowId mais recente, ou seja, o maior / MAX() para cada usuário existente. Se RowId não for monotônico esta solução não funcionará e alguma outra medida de tempo será necessária. Observe que as lacunas estão corretas, portanto, exclusões e IDENTIDADE / SEQUÊNCIA são aceitáveis. Dependendo de suas cardinalidades, o desempenho pode ser melhorado pela adesão do INNER ao NewData neste CTE.

    CTE NextSequence mapeia o RowId para um valor de sequência existente e calcula o próximo número de sequência. O módulo (%) faz o wrap-around em 9999. Mudei meus dados de amostra disso na sua pergunta para que o UserId 1 seja envolvido. Estou assumindo uma linha por usuário nos novos dados. Se houver mais, você pode atribuir a cada linha de entrada uma sequência local dentro dos novos dados e adicionar & módulo ao número de sequência base existente.

    A seleção final fornece os dados a serem inseridos. Se sua tabela real tiver uma identidade, omita RowId. O uso de uma junção externa permite que novos usuários sejam inseridos. O ISNULL define as sequências de novos usuários para 1.

    Como você pode nomear objetos SEQUENCE , você pode , de uma maneira muito complicada, criar um novo para cada valor de UserId e tentar codificar qual deles extrair para cada nova linha de entrada. Como exercício seria interessante. Como sistema de produção, seria terrível. Não faça isso. A meta-codificação seria horrível e haveria algum limite para o número de objetos de sequência disponíveis em um banco de dados.

    • 1

relate perguntas

  • SQL Server - Como as páginas de dados são armazenadas ao usar um índice clusterizado

  • Preciso de índices separados para cada tipo de consulta ou um índice de várias colunas funcionará?

  • Quando devo usar uma restrição exclusiva em vez de um índice exclusivo?

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Como determinar se um Índice é necessário ou necessário

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve