1
votes

Distribution de fréquence par jour

J'ai des enregistrements de nombre d'appels arrivant à un centre d'appels. Lorsqu'un appel arrive dans un centre d'appels, un ticket est ouvert.

Disons que le ticket 1 (T1) est ouvert le 01/08/19 et qu'il reste ouvert jusqu'au 05/08/19. Donc, si une personne a lancé une requête tous les jours, le 1/8, il affichera 1 ticket ouvert ... même chose du jour 2 au jour 5 ... Je veux obtenir des enregistrements par jour pour voir combien de tickets étaient ouverts pour chaque jour .....

En bref, Distribution des fréquences par jour.

Date        # Tickets_Open
8/1/2019        2
8/2/2019        2
8/3/2019        2
8/4/2019        2
8/5/2019        2
8/6/2019        1
8/7/2019        0
8/8/2019        0
8/9/2019        0
8/10/2019       0 

Résultat:

Résultat p >

Ticket     Open_date       Close_date   
    T1     8/1/2019      8/5/2019   
    T2     8/1/2019      8/6/2019   


1 commentaires

Pour une poignée de dates, la réponse de Tim est probablement la meilleure approche. Si vous essayez de le faire pendant une longue période sur un grand ensemble de données, il existe des approches plus efficaces. Je recommanderais d'accepter une réponse ici et de poser une autre question si tel est le cas.


3 Réponses :


3
votes

Nous pouvons gérer vos besoins en utilisant un tableau calendrier , qui stocke toutes les dates couvrant la plage complète de votre ensemble de données.

WITH dates AS (
    SELECT '2019-08-01' AS dt UNION ALL
    SELECT '2019-08-02' UNION ALL
    SELECT '2019-08-03' UNION ALL
    SELECT '2019-08-04' UNION ALL
    SELECT '2019-08-05' UNION ALL
    SELECT '2019-08-06' UNION ALL
    SELECT '2019-08-07' UNION ALL
    SELECT '2019-08-08' UNION ALL
    SELECT '2019-08-09' UNION ALL
    SELECT '2019-08-10'
)

SELECT
    d.dt,
    COUNT(t.Open_date) AS num_tickets_open
FROM dates d
LEFT JOIN tickets t
    ON d.dt BETWEEN t.Open_date AND t.Close_date
GROUP BY
    d.dt;

Notez que dans pratique si vous prévoyez d'avoir cette exigence de rapport à long terme, vous voudrez peut-être remplacer les dates CTE ci-dessus par un tableau de dates de bonne foi.


0 commentaires

0
votes

Cette solution génère la liste des dates à partir de la table des tickets en utilisant la récursivité CTE et calcule le nombre:

WITH Tickets(Ticket, Open_date, Close_date) AS
( 
SELECT "T1", "8/1/2019", "8/5/2019"
UNION ALL
SELECT "T2", "8/1/2019", "8/6/2019"
),
Ticket_dates(Ticket, Dates) as
(
SELECT t1.Ticket, CONVERT(DATETIME, t1.Open_date)
FROM Tickets t1
UNION ALL
SELECT t1.Ticket, DATEADD(dd, 1, CONVERT(DATETIME, t1.Dates))
FROM Ticket_dates t1
inner join Tickets t2 on t1.Ticket = t2.Ticket
where DATEADD(dd, 1, CONVERT(DATETIME, t1.Dates)) <= CONVERT(DATETIME, t2.Close_date)
)
SELECT CONVERT(varchar, Dates, 1),  count(*)
FROM Ticket_dates
GROUP by Dates
ORDER by Dates


0 commentaires

0
votes

Une astuce "à usage général" est de générer une série de nombres, ce qui peut être fait en utilisant les CTE mais il existe de nombreuses alternatives, et à partir de cela, créer la plage de dates nécessaire. Une fois que cela existe, vous pouvez laisser joindre les données de votre ticket à cela, puis compter par date.

+--------+---------------------+--------------+
| rownum |       on_date       | tickets_open |
+--------+---------------------+--------------+
|      1 | 01.08.2019 00:00:00 |            2 |
|      2 | 02.08.2019 00:00:00 |            2 |
|      3 | 03.08.2019 00:00:00 |            2 |
|      4 | 04.08.2019 00:00:00 |            2 |
|      5 | 05.08.2019 00:00:00 |            2 |
|      6 | 06.08.2019 00:00:00 |            1 |
+--------+---------------------+--------------+

Notez également que j'utilise un cross apply dans cet exemple pour " attachez "les dates min et max de vos billets à chaque ligne numérotée. Vous devrez inclure votre propre logique sur les données à sélectionner ici.

;WITH
  cteDigits AS (
      SELECT 0 AS digit UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL
      SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9
      )
, cteTally AS (
      SELECT 
              [1s].digit 
            + [10s].digit * 10
            + [100s].digit * 100  /* add more like this as needed */
            AS num
      FROM cteDigits [1s]
      CROSS JOIN cteDigits [10s]
      CROSS JOIN cteDigits [100s] /* add more like this as needed */
      )
select 
      n.num + 1 rownum
    , dateadd(day,n.num,ca.min_date) as on_date
    , count(t.Ticket) as tickets_open
from cteTally n
cross apply (select min(Open_date), max(Close_date) from mytable) ca (min_date, max_date)
left join mytable t on dateadd(day,n.num,ca.min_date) between t.Open_date and t.Close_date
where dateadd(day,n.num,ca.min_date) <= ca.max_date
group by
      n.num + 1
    , dateadd(day,n.num,ca.min_date)
order by 
      rownum
;

résultat:

CREATE TABLE mytable(
   Ticket     VARCHAR(8) NOT NULL PRIMARY KEY
  ,Open_date  DATE  NOT NULL
  ,Close_date DATE  NOT NULL
);
INSERT INTO mytable(Ticket,Open_date,Close_date) VALUES ('T1','8/1/2019','8/5/2019');
INSERT INTO mytable(Ticket,Open_date,Close_date) VALUES ('T2','8/1/2019','8/6/2019');


0 commentaires