iT邦幫忙

2

趣味SQL 又來了! 以今天為基準,往前400年,往後400年,統計13號出現在星期幾的總數.

sql

以今天為基準,往前400年,往後400年,統計13號出現在星期幾的總數.
例如這樣的.

+-----+-------+
| dow | count |
+-----+-------+
|   0 |  1374 |
|   1 |  1370 |
|   2 |  1370 |
|   3 |  1374 |
|   4 |  1368 |
|   5 |  1376 |
|   6 |  1368 |
+-----+-------+
(7 rows)

看來13號星期五是最多的呢.

我是用這樣的方式:

select extract(dow from d) dow
     , count(*) 
  from generate_series(date 'today' - interval '400 years'
       , date 'today' + interval '400 years'
       , interval '1 day') as g(d) 
 where extract(day from d) = 13 
 group by 1 
 order by 1;
看更多先前的討論...收起先前的討論...
小魚 iT邦大師 1 級 ‧ 2020-02-04 07:55:05 檢舉
其實看起來不會差太多, 不過這樣也符合機率原則.
這個認真來說,已經超過sql的應用了吧@@"
因為......根本沒資料啊。
可以把日期時間看作是一直在進行產出的資料.
如果是假設現有資料有存在的話。好像沒啥難度了吧?
就mysql而言也已經有現在的格式time直接用了。

這題我就不跟了。感覺沒啥挑戰性。
自己生資料這段還是需要思考一下的XD

2 個回答

0
暐翰
iT邦大師 1 級 ‧ 2020-02-03 21:29:12
最佳解答

首先謝謝大大又提供好玩的題目 :D


以下是第一直覺寫法,使用SQL-Server的T-SQL來解這個問題
假如有其他靈感會再更新

之前舊的作法Demo Link SQL Server 2012 | db<>fiddle


更新後作法:
主要處理邏輯 : 只需要知道800年總共有9600個月 = 只會有9600個13號來處理資料就可以

declare @now date = '2020-2-3'; --以今天為基準
--統計13號出現在星期幾的總數
with cte as (
	select datepart(dw, convert(nvarchar(8),dateadd(month,val,dateadd(year,-400,@now)),121) + '13') week 
	from ( 
		--藉由spt_values + cross join得到多rows資料
		select row_number() over (order by(select 1)) - 1  val
		from master..spt_values T1,master..spt_values  T2
		where t1.type = 'P'
	) T
	where val <= 800 * 12 - 1 
)
select week dow ,count(1) count 
from cte 
group by week
order by dow;

Demo Link SQL Server 2012 | db<>fiddle

看更多先前的回應...收起先前的回應...

感覺你的判斷大於13那裡有點繁瑣.有點辛苦啊.是不是直接用函數判斷13號會比較方便.

暐翰 iT邦大師 1 級 ‧ 2020-02-03 22:08:58 檢舉

一級屠豬士 是,我這邊修改一下 :D

有時候會繞進去想太複雜了.

暐翰 iT邦大師 1 級 ‧ 2020-02-03 22:20:41 檢舉

是,一開始想太多了 XD

2
tw70126_tw
iT邦新手 5 級 ‧ 2020-02-04 11:58:54
DECLARE @StartDate DATE = '19800901'
  , @EndDate DATE = '20201001';

WITH allDays AS
(
    SELECT DATEADD(DAY, 0, @StartDate) AS generate_Date
    UNION ALL
    SELECT DATEADD(DAY, 1, generate_Date)
    FROM AllDays
    WHERE generate_Date < @EndDate
)SELECT  DATEPART(weekday,generate_Date) as dayOfWeek,count (0) countTimes
FROM    AllDays
where day(generate_Date) = 13
group by DATEPART(weekday,generate_Date)
OPTION (MAXRECURSION 0)

創造一個+1迴圈 產生日期

我要發表回答

立即登入回答