简体   繁体   中英

Convert Week Number to First day of Week

I have a table with a column containing a date. My goal is to group by week, using the first day of the week (monday). Currently, I have it grouping only by week number and I cannot figure out how to get week number to convert to the date of the week begin. Current code:

SELECT 
        DATEPART(week, CONVERT_TIMEZONE('UTC', 'America/Denver', fact_completed_offer_engagements.verified)) AS "fact_completed_offer_engagements.verified_date",
        COUNT(DISTINCT CASE WHEN fact_completed_offer_engagements.activated IS NOT NULL THEN fact_completed_offer_engagements.customer_offer_id ELSE NULL END) AS "fact_completed_offer_engagements.shopping_list_placements"
FROM public.fact_completed_offer_engagements AS fact_completed_offer_engagements
LEFT JOIN public.offers AS offers ON fact_completed_offer_engagements.offer_id = offers.id
LEFT JOIN public.campaigns AS campaigns ON offers.campaign_id = campaigns.id
LEFT JOIN public.contracts AS contracts ON campaigns.contract_id = contracts.id

  WHERE 
    (campaigns.id = ?)
                OR campaigns.id = ?
group by 1
ORDER BY 1
limit 1000

Thanks for any help!

You might have a look here: https://stackoverflow.com/a/38601630/5089204

Be aware, that you are using culture specific logic. The first day of week is Monday, but not everywhere...

Use @@DATEFIRST to calculate a culture independant date like this

DECLARE @testDate DATETIME=GETDATE();
SELECT @testDate - (@@DATEFIRST + DATEPART(WEEKDAY,@testDate)) % 7 + 1; 

The result is always the Sunday before the date given. Add +2 at the end and you'll get your Monday.

UPDATE

You might want to cast the result to DATE in order to get rid of the time component...

You can calculate week commencing date using the following sequence generation and aggregation CTEs. Just join your query to it on week number and alter the start date to match your requirements.

-- Set fist day of week as Monday
SET DATEFIRST 1;

;WITH CTE_Nums AS (
              SELECT    ROW_NUMBER() OVER (ORDER BY ob.object_id) AS Num
              FROM      sys.all_objects AS ob
             ),
CTE_WeekBegin AS (
SELECT DATEPART(WEEK, DATEADD(DAY, Num, '2016-01-01')) AS WeekNo, MIN(DATEADD(DAY, Num, '2016-01-01')) AS Date
FROM CTE_Nums
GROUP BY DATEPART(WEEK, DATEADD(DAY, Num, '2016-01-01'))
)
SELECT wb.Date, ...
FROM ...
INNER JOIN CTE_WeekBegin wb ON wb.WeekNo = xx.xx;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM