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
3 Réponses :
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.
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
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');
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.