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[window-functions](dba)

Martin Hope
michaelosmith
Asked: 2022-08-30 03:20:33 +0800 CST

SUM em execução cumulativa para intervalos de datas com intervalos

  • 2

Estou procurando ajuda para obter uma soma contínua da diferença entre duas datas que estão em linhas separadas.

A tabela se parece com:

ID do Cliente nome autopay_status contract_id data de início data final
1 Contrato 1 Inativo 1111 "2019-08-30" "2020-02-29"
1 Contrato 1 Inativo 1112 "2020-02-29" "2020-08-29"
1 Contrato 1 Ativo 1113 "2020-08-29" "2021-02-28"
2 Contrato 2 Inativo 2221 "2019-08-30" "2020-02-29"
2 Contrato 2 Inativo 2222 "2020-02-29" "2020-08-29"
2 Contrato 2 Ativo 2223 "2020-08-29" "2021-02-28"
3 Contrato 3 Inativo 3331 "2019-08-30" "2020-02-29"
3 Contrato 3 Inativo 3332 "2020-03-29" "2020-09-29"
3 Contrato 3 Inativo 3333 "2020-09-29" "2021-03-28"
3 Contrato 3 Ativo 3334 "2021-03-28" "2021-09-28"

Eu tenho uma consulta que analisa a data_final anterior e, se estiver dentro de um dia, esse é um contrato contínuo.

SELECT
    case when
        (start_date - coalesce(lag(end_date) over (partition by client_id order by end_date), end_date)::date)::int <= 1 then true
         else false
    end as continous_contract,
    end_date - start_date as contract_days,
    client_id,
    contract_id,
    autopay_status,
    start_date,
    end_date
FROM
    client_contracts
ORDER BY
    client_id, start_date

Isso adiciona duas colunas de alias extras.

contrato_contínuo contrato_dias ID do Cliente nome autopay_status contract_id data de início data final
verdadeiro 183 3 Contrato 3 Inativo 3331 "2019-08-30" "2020-02-29"
falso 184 3 Contrato 3 Inativo 3332 "2020-03-29" "2020-09-29"
verdadeiro 183 3 Contrato 3 Inativo 3333 "2020-09-29" "2021-03-28"
verdadeiro 182 3 Contrato 3 Ativo 3334 "2021-03-28" "2021-09-28"

Meu objetivo aqui é resumir os dias em que um cliente teve um contrato contínuo para que a tabela seja semelhante à abaixo para o exemplo acima:

soma_dias contrato_contínuo contrato_dias ID do Cliente
183 verdadeiro 183 3
184 falso 184 3
367 verdadeiro 183 3
549 verdadeiro 182 3
733 verdadeiro 184 3
181 falso 181 3

Eu coloquei a consulta abaixo, mas ela resume apenas os dois valores anteriores.

SELECT
*
FROM
(
    SELECT
        *,
        case
            when cc.continuous_contract = true then
                cc.contract_days + coalesce(lag(cc.contract_days) over (partition by cc.client_id), 1)
            else cc.contract_days
        end as added_contract_days
    FROM (
        SELECT
            case when
                (start_date - coalesce(lag(end_date) over (partition by client_id order by end_date), end_date)::date)::int <= 1 then true
                 else false
            end as continuous_contract,
            end_date - start_date as contract_days,
            client_id,
            contract_id,
            autopay_status,
            start_date,
            end_date
        FROM
            client_contracts
        ) as cc
    ) as ccc

Estou feliz em mudar qualquer coisa para fazer este trabalho.

Fiddle para auxiliar na visualização de dados e estrutura: Fiddle

postgresql window-functions
  • 1 respostas
  • 46 Views
Martin Hope
Jason
Asked: 2022-08-02 14:45:36 +0800 CST

Soma acumulada em um período de meses

  • 2

Eu tenho essa tabela:

mês_rep frutas colhido
01-09-2021 139 139
01-10-2021 143 11
01-11-2021 152 14
01-12-2021 112 9
01-01-2022 133 10
01-02-2022 145 12
01-03-2022 123 5
01-04-2022 111 4
01-05-2022 164 9
01-06-2022 135 12
01-07-2022 124 14
01-08-2022 144 18
01-09-2022 111 111
01-10-2022 108 13
01-11-2022 123 7
01-12-2022 132 20

Eu quero criar uma nova coluna chamada soldque é baseada em um cálculo - que será uma soma em execução harvestedem um período de meses (set-jun). Todo mês de setembro, soldsempre será 1 (ou 100 em por cento). O cálculo para outubro de 2021 será fruits/ ( harvested+ harvested_Nov) = 143 / 11 + 139.

Para os restantes meses de 2021, segue o mesmo formato: fruits/ ( harvested+ harvested_until_Sep) --> esta será uma soma corrente, a partir do mês em que se encontra, e termina em setembro do ano anterior.

Outro exemplo para 2022 é o cálculo para março de 2022 = fruits/ ( harvested+ harvested_Feb_2022+ harvested_Jan_2022+ harvested_Dec_2021+ harvested_Nov_2021+ harvested_Oct_2021+ harvested_Sep_2021) = 123 / (5+12+10+9+14+11+139).

A tabela deve ficar assim:

mês_rep frutas colhido vendido
01-09-2021 139 139 1
01-10-2021 143 11 0,95
01-11-2021 152 14 0,93
01-12-2021 112 9 0,65
01-01-2022 133 10 ..
01-02-2022 145 12 ..
01-03-2022 123 5 ..
01-04-2022 111 4 ..
01-05-2022 164 9 ..
01-06-2022 135 12 ..
01-07-2022 124 14 nulo
01-08-2022 144 18 nulo
01-09-2022 111 111 1
01-10-2022 108 13 0,87
01-11-2022 123 7 0,94
01-12-2022 132 20 ..

Eu tentei isso:

select 
    month_rep,
    fruits,
    harvested,
    case when extract(month from "month_rep") in (7, 8) then null
         when extract(month from "month_rep") = 9 then 1
        else ROUND(fruits / sum(harvested) over (order by month_rep), 2) end sold
from my_table 

Isso funciona bem, mas apenas quando tenho dados antes de setembro de 2022. Eu quero que julho e agosto tenham null sold- o que funciona. Após agosto, setembro de 2022 deve ser um novo período onde soldé 1. Depois disso, outubro de 2022 será calculado como fruits/ ( harvested+ harvested_Sep_2022) - onde iniciamos um novo período para o 2º período de setembro de 2022 a junho de 2023.

Existe uma maneira de agrupar esses "períodos" e ter a soma acumulada sobre isso? Talvez eu precise encontrar uma maneira de agrupar o período e particionar a partir disso.

postgresql window-functions
  • 1 respostas
  • 109 Views
Martin Hope
Healyhatman
Asked: 2022-02-14 16:26:25 +0800 CST

Obter linhas agrupadas por uma chave estrangeira com contagem de valores consecutivos

  • 2

Eu tenho um banco de dados SQL Server com uma transactionstabela com client_id, datee is_cancelled.

Estou tentando obter os client_ids que têm 3 ou mais transações em uma linha marcadas como is_cancelled, junto com a contagem in_a_row. Cheguei ao seguinte, o que me dá um 1 para is_same quando os suportes is_cancelled são consecutivos e um total de transações canceladas (que não é bem o que eu preciso)

SELECT 
client_id,
date,
is_same,
SUM(is_same) OVER (PARTITION BY client_id ORDER BY date) AS sum_same,
transCancelled
FROM
(
    SELECT
    client_id,
    LAG(is_cancelled) OVER (PARTITION BY client_id ORDER BY date) AS previous_cancelled,
    CASE 
        WHEN is_cancelled = LAG(is_cancelled) OVER (PARTITION BY client_id ORDER BY date)
        THEN 1
        ELSE 0
    END as is_same,
    date,
    is_cancelled
    FROM transactions
    WHERE deleted_at IS NULL -- Ignore soft-deleted rows
) AS t_01
WHERE previous_cancelled = 1
ORDER BY date

Mexa com dados de amostra: https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=a0c9b12203ab2d0c83f73604ccc9d0a0

Dados esperados (client_id, contagem) 1, 3 3, 6

sql-server window-functions
  • 1 respostas
  • 182 Views
Martin Hope
Carol.Kar
Asked: 2021-12-26 11:30:04 +0800 CST

Obtendo a classificação da linha

  • 1

estou usando mysql Ver 14.14 Distrib 5.7.21, for Linux (x86_64).

Estou tendo uma referência de tabela:

CREATE TABLE `referrals` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `referred_by` bigint(20) unsigned DEFAULT NULL,
  `referral_token` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `email` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `referrals_email_unique` (`email`)
);

Na tabela você basicamente insere a pessoa e quem a encaminhou.

Criei a seguinte tabela de classificação:

select
        referred_by,
        count(referred_by) as referred_by_count,
            @curRank := @curRank + 1 AS rank
from
        referrals r,
    (
    SELECT
        @curRank := 0) o
group by
        referred_by
order by
        referred_by_count DESC;

Isso me dá:

referido por refer_by_count classificação
10 3 3
2 2 1
3 2 2
13 2 5
11 2 6
15 1 8
12 1 9
4 1 4
9 1 7

No entanto, gostaria de obter:

referido por refer_by_count classificação
10 3 1
2 2 2
3 2 3
13 2 4
11 2 5
15 1 6
12 1 7
4 1 8
9 1 9

Ver no DB Fiddle

Eu criei o seguinte dbfiddle usando o plugin faker php.

Eu tentei usar a RANK()função mysql. No entanto, estou lutando como usá-lo corretamente.

Eu aprecio suas respostas!

mysql window-functions
  • 2 respostas
  • 104 Views
Martin Hope
r2k2
Asked: 2021-08-03 11:24:25 +0800 CST

Contagem de linhas nulas que precedem cada valor não nulo

  • 0

Preciso responder a seguinte pergunta:

Qual é o número médio de envios de e-mail que leva antes que um cliente abra um e-mail? Eu sei que preciso contar o número de linhas entre cada Open_Date para obter o número de envios de email entre cada abertura. Percebo que preciso adicionar a função row_number () para isso, mas não consigo chegar à coluna desejada na minha segunda captura de tela.

Algo a ter em mente, precisarei obter um "CounttilOpens" médio por endereço de e-mail. No meu exemplo abaixo, tenho dois endereços de e-mail diferentes e suas respectivas datas de envio e abertura e preciso que a consulta funcione de forma independente para cada endereço de e-mail.

Meus dados estão estruturados da seguinte forma:

insira a descrição da imagem aqui

Preciso de uma consulta que me ajude a obter uma nova coluna como esta que reinicia para cada endereço de e-mail e para cada intervalo de datas abertas:

insira a descrição da imagem aqui

partitioning window-functions
  • 1 respostas
  • 359 Views
Martin Hope
jsf80238
Asked: 2021-07-02 14:57:33 +0800 CST

Calcular um valor cumulativo com um determinado tempo

  • 0

Quero identificar clientes que gastaram mais de D dólares em um período de P horas. Suponha que D=$10 e P=48. Em seguida, nos dados da transação abaixo:

CUSTOMER         STAMP        AMOUNT
--------         -----        ------
   A     2021-06-02 00:22:53    1.44
   A     2021-06-02 06:24:17    1.51
   A     2021-06-03 07:09:45    2.73
   A     2021-06-03 15:57:30    3.92
   A     2021-06-04 06:41:21    1.83
   B     2021-06-01 02:50:22    2.65
   B     2021-06-03 07:01:36    4.05
   B     2021-06-04 05:20:10    3.30
   B     2021-06-04 09:53:53    2.64
   B     2021-06-04 14:54:00    2.26
   C     2021-06-01 16:01:38    2.61
   C     2021-06-01 23:38:25    1.16
   C     2021-06-02 14:41:02    2.82
   C     2021-06-03 00:28:37    1.54
   C     2021-06-03 02:06:46    1.19
   C     2021-06-04 17:16:29    2.05

o cliente B atende aos critérios e os clientes A e C não (mesmo que seus gastos totais > $ 10).

Eu sei como usar funções de janelas, mas neste caso não sei de antemão o tamanho da janela.


Acho que a resposta seria algo assim:

select
  customer
, stamp
, amount
, amount > coalesce(sum(amount) over (order by extract('epoch_second', stamp)
range between 2*24*60*60 preceding and current row), 0) as is_alert
from t
where amount is not null
order by stamp

mas meu banco de dados é Snowflake e não parece oferecer suporte a essa sintaxe . Essa página diz:

Para frames de janela cumulativos: ... RANGE é semelhante a ROWS, exceto que apenas calcula o resultado para linhas que têm o mesmo valor que a linha atual (de acordo com a subcláusula ORDER BY especificada).

window-functions snowflake
  • 1 respostas
  • 36 Views
Martin Hope
a_dog_with_no_master
Asked: 2021-06-25 02:23:18 +0800 CST

Escolha o primeiro carimbo de data/hora antes de um intervalo, mas o último do dia se não houver um intervalo adequado

  • 1

Eu tenho uma coluna TIMESTAMP:

dates
2021-06-24 05:47:05
2021-06-24 09:47:05
2021-06-24 13:47:05
2021-06-24 17:47:05

Quero escolher o primeiro carimbo de data/hora de um determinado dia 3 horas ou mais antes do próximo carimbo de data/hora desse mesmo dia.

expected output:

2021-06-24 05:47:05

No entanto , se não houver um carimbo de data/hora mais de 3 horas antes de qualquer outro (nesse dia), o último carimbo de data/hora desse dia deverá ser retornado.

postgresql window-functions
  • 1 respostas
  • 399 Views
Martin Hope
kn3l
Asked: 2021-06-01 00:23:58 +0800 CST

Significado de "linhas entre 15 anteriores e 15 seguintes"

  • -1
WITH trips_by_day AS
                      (
                      SELECT DATE(trip_start_timestamp) AS trip_date,
                          COUNT(*) as num_trips
                      FROM `bigquery-public-data.chicago_taxi_trips.taxi_trips`
                      WHERE trip_start_timestamp >= '2016-01-01' AND trip_start_timestamp < '2018-01-01'
                      GROUP BY trip_date
                      ORDER BY trip_date
                      )
                      SELECT trip_date,
                          avg(num_trips)
                          OVER (
                               order by trip_date
                               rows between 15 preceding and 15 following
                               ) AS avg_num_trips
                      FROM trips_by_day

Alguém poderia me explicar o significado de rows between 15 preceding and 15 following?

sql-server window-functions
  • 2 respostas
  • 120 Views
Martin Hope
Daniel Müller
Asked: 2021-05-19 04:35:20 +0800 CST

Obtendo a linha antes de uma linha com um determinado valor no SQL

  • 1

Eu tenho uma tabela como abaixo onde as ações do usuário são armazenadas com um carimbo de data/hora. Meu objetivo é identificar a ação que aconteceu antes de uma ação específica (chamada reference_action) e contar o número dessas ações para ver quais ações acontecem antes das ações específicas e como elas são distribuídas.

Estou ciente de funções de janela como LAG() onde posso obter a linha antes de uma determinada linha, mas não consigo descobrir como incluir uma restrição como WHERE action_name = "reference_action".

O mecanismo de consulta é Presto e as tabelas são tabelas Hive, mas estou mais interessado na abordagem SQL geral, portanto, isso não deve importar muito.

sessão action_name carimbo de data/hora
1 "alguma_ação" 1970-01-01 00:01:00
1 "alguma_ação" 1970-01-01 00:02:00
1 "alguma_ação" 1970-01-01 00:03:00
1 "desired_action1" 1970-01-01 00:04:00
1 "reference_action" 1970-01-01 00:05:00
1 "alguma_ação" 1970-01-01 00:06:00
1 "alguma_ação" 1970-01-01 00:07:00
2 "alguma_ação" 1970-01-01 01:23:00
2 "alguma_ação" 01-01-1970 02:34:00
2 "desired_action1" 1970-01-01 03:45:00
2 "reference_action" 01-01-1970 04:56:00
2 "alguma_ação" 1970-01-01 05:58:00
3 "alguma_ação" 1970-01-01 01:23:00
3 "alguma_ação" 01-01-1970 02:34:00
3 "desired_action2" 1970-01-01 03:45:00
3 "reference_action" 01-01-1970 04:56:00
3 "alguma_ação" 1970-01-01 05:58:00

O resultado deve se parecer com:

ação contar
"desired_action1" 2
"desired_action2" 1

Existem duas linhas em que "desired_action1" é seguido diretamente por uma linha com "reference_action", quando ordenado por timestamp, portanto, a contagem é 2. A mesma lógica se aplica ao motivo pelo qual a contagem é 1 para "desired_action2".

O objetivo é saber o que um usuário fez antes de fazer uma compra (compra = reference_action). Para entender o que ele fez antes, quero pesquisar a ação que aconteceu antes de uma compra. Portanto, preciso saber o action_name na linha antes de um reference_action. as ações_desejadas precisam ser contadas, as ações_referência são apenas as linhas após as ações que eu quero contar e usadas para determinar quais valores devem ser contados.

sql-standard window-functions
  • 1 respostas
  • 135 Views
Martin Hope
vmachacek
Asked: 2021-04-22 02:51:06 +0800 CST

Postgres SUM sobre PARTITION BY "tolerar" valores nulos

  • 0

Eu tenho uma visão que calcula a soma contínua tomando o valor da linha anterior com base na PARTITION BYcláusula e preciso indicar que um campo na PARTITION BYcláusula pode ter nulos.

sum(s."QuantityChange") OVER (PARTITION BY s."LocationId", s."PartId", s."SupplierFacilityId" ORDER BY s."DueDate" ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS "RunningSum"

Às vezes SupplierFacilityIdé nulo e tudo bem, ainda deve ser incluído no sum()cálculo.

Isso é possível com o Postgres?

postgresql window-functions
  • 2 respostas
  • 2279 Views

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