J'ai une requête assez simple; il ressemble à ceci:
+------------+-------------+-----------------+ | order_date | pickup_date | order_to_pickup | +------------+-------------+-----------------+ | 3/29/19 | 4/3/19 | 2 | | 3/29/19 | 4/2/19 | 3 | +------------+-------------+-----------------+
Le seul problème est que je dois calculer la différence de date en jours ouvrables, pas tous les jours.
Donc, au lieu de ce qui précède requête renvoyant:
+------------+-------------+-----------------+ | order_date | pickup_date | order_to_pickup | +------------+-------------+-----------------+ | 3/29/19 | 4/3/19 | 5 | | 3/29/19 | 4/2/19 | 4 | +------------+-------------+-----------------+
Je veux qu'elle renvoie:
SELECT order_date, pickup_date, DATE_DIFF(pickup_date,order_date, day) order_to_pickup FROM `orders.table`
3 Réponses :
Je pense qu'il y a une solution intelligente à trouver si l'on considère le nombre de semaines entre les deux dates, mais voici une approche par force brute en attendant:
CREATE TEMP FUNCTION BusinessDateDiff(start_date DATE, end_date DATE) AS (
(SELECT COUNTIF(MOD(EXTRACT(DAYOFWEEK FROM date), 7) > 1)
FROM UNNEST(GENERATE_DATE_ARRAY(
start_date, DATE_SUB(end_date, INTERVAL 1 DAY))) AS date)
);
WITH OrdersTable AS (
SELECT
DATE '2019-03-29' AS order_date,
DATE '2019-04-03' AS pickup_date UNION ALL
SELECT
'2019-03-29',
'2019-04-02'
)
SELECT
order_date,
pickup_date,
BusinessDateDiff(order_date, pickup_date) AS order_to_pickup
FROM OrdersTable
ORDER BY pickup_date
+------------+-------------+-----------------+
| order_date | pickup_date | order_to_pickup |
+------------+-------------+-----------------+
| 2019-03-29 | 2019-04-02 | 2 |
| 2019-03-29 | 2019-04-03 | 3 |
+------------+-------------+-----------------+
Pour votre entrée, j'obtiens:
CREATE TEMP FUNCTION BusinessDateDiff(start_date DATE, end_date DATE) AS (
(SELECT COUNTIF(MOD(EXTRACT(DAYOFWEEK FROM date), 7) > 1)
FROM UNNEST(GENERATE_DATE_ARRAY(
start_date, DATE_SUB(end_date, INTERVAL 1 DAY))) AS date)
);
Oui! Je pense que cela me donne ce dont j'ai besoin! Je vous remercie!
Voici une méthodologie de travail pour calculer les jours ouvrables entre les dates en fonction du travail effectué dans la communauté Looker Discourse ici . L'exemple d'origine est pour Redshift, je l'ai donc adapté pour BigQuery ci-dessous.
SELECT
order_date,
pickup_date,
CAST(-1*(DATE_DIFF(order_date, pickup_date, DAY) - ((FLOOR(DATE_DIFF(order_date, pickup_date, DAY) / 7) * 2) +
CASE
WHEN EXTRACT(DAYOFWEEK FROM order_date) - EXTRACT(DAYOFWEEK FROM pickup_date) IN (1, 2, 3, 4, 5) AND EXTRACT(DAYOFWEEK FROM pickup_date) != 0 THEN 2
ELSE 0
END +
CASE
WHEN EXTRACT(DAYOFWEEK FROM order_date') != 0 AND EXTRACT(DAYOFWEEK FROM pickup_date) = 0 THEN 1
ELSE 0
END +
CASE
WHEN EXTRACT(DAYOFWEEK FROM order_date) = 0 AND EXTRACT(DAYOFWEEK FROM pickup_date) != 0 THEN 1
ELSE 0 END)) AS int64) AS weekdays
FROM
`orders.table`
En appliquant ceci à votre ensemble de données, nous obtenons:
SELECT
CAST(-1*(DATE_DIFF(DATE '2019-01-01', DATE '2019-01-31', DAY) - ((FLOOR(DATE_DIFF(DATE '2019-01-01', DATE '2019-01-31', DAY) / 7) * 2) +
CASE
WHEN EXTRACT(DAYOFWEEK FROM DATE '2019-01-01') - EXTRACT(DAYOFWEEK FROM DATE '2019-01-31') IN (1, 2, 3, 4, 5) AND EXTRACT(DAYOFWEEK FROM DATE '2019-01-31') != 0 THEN 2
ELSE 0
END +
CASE
WHEN EXTRACT(DAYOFWEEK FROM DATE '2019-01-01') != 0 AND EXTRACT(DAYOFWEEK FROM DATE '2019-01-31') = 0 THEN 1
ELSE 0
END +
CASE
WHEN EXTRACT(DAYOFWEEK FROM DATE '2019-01-01') = 0 AND EXTRACT(DAYOFWEEK FROM DATE '2019-01-31') != 0 THEN 1
ELSE 0 END)) AS int64) AS weekdays
Cela devrait être la solution simplifiée et non bruteforce mentionnée par @Elliott Brossard:
select
order_date,
pickup_date,
case
when date_diff(pickup_date, order_date, week) > 0
then date_diff(pickup_date, order_date, day) - (date_diff(pickup_date, order_date, week) * 2)
else
date_diff(pickup_date, order_date, day)
end
from `orders.table`
Qu'est-ce qui définit un jour ouvrable? Chaque jour de la semaine est-il un jour ouvrable ou avez-vous un calendrier des jours fériés qui ne compte pas non plus comme des jours ouvrables?
@ElliottBrossard Nous pouvons simplement dire pour cela que les jours ouvrables sont strictement du lundi au vendredi
cela peut vous aider: stackoverflow.com/questions / 252519 /…