Kiedy najlepiej zamieścić pytanie w tagu sql-server na StackOverflow? Część I

Że co?

Mamy proste zadanie. Określić medianę czasu odpowiedzi na pytanie zadane na StackOverflow w tagu “sql-server” w czasie tygodnia. Kiedy najszybciej otrzymamy odpowiedź? O której godzinie zadać pytanie? Którego dnia tygodnia?

Użyjemy do tego celu średniej bazy StackOverflow z roku 2013 (trochę stare dane) stąd.

Zaczynamy!

Dane na temat wpisów znajdują się w tabeli [dbo].[Posts]. Jednakże, znajdują się tam tak samo pytania jak i wszystkie odpowiedzi! Zerknijmy na wyniki.

SELECT TOP 100
    *
FROM
    [dbo].[Posts]

Poszukując tego czego szukamy możemy określić, że:

  • Id to unikatowy numer wpisu w tabeli
  • CreationDate to data utworzenia pytania bądź odpowiedzi
  • PostTypeId to odwołanie do tabeli [dbo].[PostTypes], która określa jakiego typu jest dany wpis
  • ParentId to odwołanie do tabeli [dbo].[Posts] ale z Id pytania (czyli <> 0 jednoznacznie wskazuje, że jest to odpowiedź)
  • Tags to tagi załączone do pytania (odpowiedzi ich nie mają), ale wszystkie na raz w jednym polu

Mając tę wiedzę, spróbujmy wyciągnąć wszystkie pytania pod tagiem “sql-server”.

SELECT
    [Id],
	[CreationDate],
	[Tags]
FROM
    [dbo].[Posts]
WHERE
   [Tags] LIKE '%<sql-server>%';

Dostaliśmy w wyniku 82 248 pytań pod tagiem “sql-server”. Nieźle! Czas na znalezienie pierwszej odpowiedzi do każdego z nich.

SELECT
    p.[Id] as [PostId],
	p.[CreationDate] as [PostCreationDate],
	p.[Tags] as [PostTags],
	pFA.[Id] as [AnswerId],
	pFA.[CreationDate] as [AnswerCreationDate]
FROM
    [dbo].[Posts] p
CROSS APPLY
    (SELECT TOP(1)
        [Id],
        [CreationDate]
    FROM
        [dbo].[Posts] pA
    WHERE
        p.[Id] = pA.[ParentId]
    ORDER BY
        pA.[CreationDate]) pFA
WHERE
   p.[Tags] LIKE '%<sql-server>%';

Dlaczego CROSS APPLY a nie OUTER APPLY? Nie interesują nas aktualnie pytania bez odpowiedzi, czym zaciemnimy sobie trochę wyniki naszej analizy, ale co tam.

I tutaj muszę się zatrzymać na chwilę, bo plan zapytania jest cudowny, a dokładniej jeden jego element <3

Widzicie go? Jak nie to jeszcze wrócimy do tego 😉 Koniec przerwy.

W wyniku mamy 80 283 wiersze. Super, czyli tylko ~2 tysiące pytań pozostało bez odpowiedzi! To teraz tylko wyliczyć czas w sekundach pomiędzy zadaniem pytania a pierwszą odpowiedzią, oraz wyznaczenie dnia tygodnia + czau zadania pytania.

SELECT
    p.[Id] as [PostId],
    DATEDIFF(SECOND,p.[CreationDate],pFA.[CreationDate]) as [TimeElapsedInSeconds],
    DATEPART(WEEKDAY,p.[CreationDate]) as [WeekdayOfQuestion],
    CAST(p.[CreationDate] as TIME(0)) as [TimeOfQuestion]
FROM
    [dbo].[Posts] p
CROSS APPLY
    (SELECT TOP(1)
        [Id],
        [CreationDate]
    FROM
        [dbo].[Posts] pA
    WHERE
        p.[Id] = pA.[ParentId]
    ORDER BY
        pA.[CreationDate]) pFA
WHERE
   p.[Tags] LIKE '%<sql-server>%';

Mamy to! Zwróćcie uwagę na to co wyszło nam w kolumnie [WeekdayOfQuestion]. Niedziele są oznaczone jako 1! Tak, domyślnie SQL Server w większości ustawień traktuje niedzielę jak pierwszy dzień tygodnia. Tutaj nie będziemy tego zmieniać, ale zainteresowanych odsyłam do wuja Google i zapytania “SET DATEFIRST SQL Server“. Ponadto godziny z sekundami to tak średnio, najlepiej jakbyśmy to badali w “grupach” naliczanych co 15 minut. Let’s fix it!

SELECT
    p.[Id] as [PostId],
    DATEDIFF(SECOND,p.[CreationDate],pFA.[CreationDate]) as [TimeElapsedInSeconds],
    DATEPART(WEEKDAY,p.[CreationDate]) as [WeekdayOfQuestion],
    CAST(CASE
        WHEN DATEPART(MINUTE,p.[CreationDate]) BETWEEN 0 AND 14 THEN
            TIMEFROMPARTS(DATEPART(HOUR,p.[CreationDate]),0,0,0,0)
        WHEN DATEPART(MINUTE,p.[CreationDate]) BETWEEN 15 AND 29 THEN
            TIMEFROMPARTS(DATEPART(HOUR,p.[CreationDate]),15,0,0,0)
        WHEN DATEPART(MINUTE,p.[CreationDate]) BETWEEN 30 AND 44 THEN
            TIMEFROMPARTS(DATEPART(HOUR,p.[CreationDate]),30,0,0,0)
        ELSE
            TIMEFROMPARTS(DATEPART(HOUR,p.[CreationDate]),45,0,0,0)
    END AS TIME(0)) as [TimeOfQuestion]
FROM
    [dbo].[Posts] p
CROSS APPLY
    (SELECT TOP(1)
        [Id],
        [CreationDate]
    FROM
        [dbo].[Posts] pA
    WHERE
        p.[Id] = pA.[ParentId]
    ORDER BY
        pA.[CreationDate]) pFA
WHERE
   p.[Tags] LIKE '%<sql-server>%';

Yay, już prawie! To teraz jeszcze tylko mediana per połączenie dzień tygodnia i czas i jesteśmy w domu.

;WITH RawData AS (
SELECT
    p.[Id] as [PostId],
    DATEDIFF(SECOND,p.[CreationDate],pFA.[CreationDate]) as [TimeElapsedInSeconds],
    DATEPART(WEEKDAY,p.[CreationDate]) as [WeekdayOfQuestion],
    CAST(CASE
        WHEN DATEPART(MINUTE,p.[CreationDate]) < 15 THEN
            TIMEFROMPARTS(DATEPART(HOUR,p.[CreationDate]),0,0,0,0)
        WHEN DATEPART(MINUTE,p.[CreationDate]) BETWEEN 15 AND 29 THEN
            TIMEFROMPARTS(DATEPART(HOUR,p.[CreationDate]),15,0,0,0)
        WHEN DATEPART(MINUTE,p.[CreationDate]) BETWEEN 30 AND 44 THEN
            TIMEFROMPARTS(DATEPART(HOUR,p.[CreationDate]),30,0,0,0)
        ELSE
            TIMEFROMPARTS(DATEPART(HOUR,p.[CreationDate]),45,0,0,0)
    END AS TIME(0)) as [TimeOfQuestion]
FROM
    [dbo].[Posts] p
CROSS APPLY
    (SELECT TOP(1)
        [Id],
        [CreationDate]
    FROM
        [dbo].[Posts] pA
    WHERE
        p.[Id] = pA.[ParentId]
    ORDER BY
        pA.[CreationDate]) pFA
WHERE
   p.[Tags] LIKE '%<sql-server>%'
)
SELECT DISTINCT
    [WeekdayOfQuestion],
    [TimeOfQuestion],
    PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY [TimeElapsedInSeconds]) OVER (PARTITION BY [WeekdayOfQuestion],[TimeOfQuestion]) AS [Median]
FROM
    [RawData]
ORDER BY
    [Median];

Chwilę to trwało, ale już wiemy. Najlepiej zadawać pytania w sobotę między 02:15:00 a 02:29:59 czasu StackOverflowowego! A najgorzej między 07:00:00 a 07:14:59 w niedzielę!
Chyba…

Zakończenie?

Oczywiście, że nie, bo nasze zapytanie chodzi jak roczne dziecko, czyli ledwo. W następnym wpisie spróbujemy coś z tym zrobić.

Oki, to pa!

Zobacz także:

  • Piotr Szymański

    Kategoria:

    Hejka naklejka! Google przeprowadza restrukturyzację swojego zespołu finansowego, kładąc większy nacisk na inwestycje w sztuczną inteligencję. Zmiany, o których poinformowała główna dyrektor finansowa Google, Ruth Porat, obejmują zwolnienia oraz przeniesienia pracowników i są odpowiedzią na spowolnienie wzrostu przychodów z reklam, jednocześnie stawiając na rosnącą rolę AI. CFO zaznaczyła, że restrukturyzacja jest częścią szerszej strategii przystosowania […]
  • Piotr Szymański

    Kategoria:

    Cześć! Zapraszam do podsumowania minionych 2 tygodni, wiadomości, które zaciekawiły mnie podczas surfowania po sieci telekomunikacyjnej Internet. Sekretarz Sił Powietrznych USA Frank Kendall ogłosił plany lotu myśliwcem F-16 sterowanym przez sztuczną inteligencję. Próba ma odbyć się wiosną tego roku i ma na celu zaprezentowanie potencjału sztucznej inteligencji w walce powietrznej, podkreślając przejście wojska w kierunku […]
  • Piotr Szymański

    Kategoria:

    Hejka naklejka! Świat jest podzielony. Jak zawsze, można by rzec. Wiecznie żywa reguła „dziel i rządź”, można by rzec. Świat podzielony na zwolenników sernika z rodzynkami, jak i bez rodzynków; wielbicieli sałatki jarzynowej jak i ludzi pozbawionych gustu; ludzi jeżdżących BMW, jak i masochistów, i tak dalej, i tym podobne. Przychodzę tu jednak ponad pewnymi […]
  • Piotr Szymański

    Kategoria:

    Siemson sportowe świry! Dumni po zwycięstwie, wierni po porażce. Tym razem jednak bez wstydu, hańby i kompromitacji. Nie podejrzewam naszego sztabu szkoleniowego o klasyczną inspirację rozwiązaniem stosowanym w Liverpoolu, natomiast nie miał bym nic przeciwko. We współpracy z Google DeepMind powstał bowiem TacticAI, model predykcyjny wspomagający wysiłki trenerów. Już w 2021 potrafił zgadnąć gdzie piłkarz […]
  • Piotr Szymański

    Kategoria:

    Hæ vinir! Dinozaury. Kto z nas nie byłby na pewnym etapie życia zafascynowany tymi uroczymi gadami. Nawet nie wiecie, ile Nas z nimi łączy! Nie tylko tak samo jesteśmy owodniowcami, ale i wyginiemy. Może nawet całkiem niedługo. Mrocznie się zrobiło, nie? Ale może zakończymy jakimś przyjemnym akcentem, więc bądźcie nastrojeni. Raport, stworzony przez Gladstone AI […]