Tävlingsuppgift 2013

En sökmotor registrerar vilka sökord som anges och vilken tidpunkt. Exempelvis:

Tid Sökord
12:00 SSIS,ETL
12:01 ETL,SSIS
12:02 SQL
13:00 SSIS,ETL

Sökorden separeras med kommatecken och varje sökord kan bara finnas med en gång. Ordningen på sökord har ingen betydelse, så de två första raderna är ekvivalenta.

Vi har blivit ombedda att skapa en rapport som grupperar ihop sökningarna i grupper med samma sökord och högst 30 minuter mellan närliggande sökningar. En grupp kan bli hur lång som helst. Så länge det kommer en ny sökning inom 30 minuter så förlängs gruppen. I exemplet ovan betyder det då att de två översta raderna bildar en grupp, den tredje raden blir en grupp och den sista raden också blir en egen grupp.

Definitioner

Här är SQL-definitionen av vår tabell med indata

CREATE TABLE [dbo].[Searches](
    [EventTime] [datetime2](0) NOT NULL,
    [SearchWords] [varchar](200) NOT NULL,
    CONSTRAINT [PK_Searches] PRIMARY KEY CLUSTERED 
    (
        [EventTime] ASC,
        [SearchWords] ASC
    )
);

Utdata skall lagras i en tabell med en rad för varje grupp. Raden skall innehålla starttid (första sökningen i gruppen), sluttid (sista sökningen i gruppen), antal sökningar i gruppen och vilka sökord. Ordningen på sökorden har ingen betydelse. Alla jämförelser är också case-insensitive (collation är Finnish_Swedish_CI_AS).

Här är SQL-definitionen av tabellen för utdata

CREATE TABLE [dbo].[SearchGroups](
    [StartTime] [datetime2](0) NOT NULL,
    [EndTime] [datetime2](0) NOT NULL,
    [NumberOfSearches] [int] NOT NULL,
    [SearchWords] [varchar](200) NOT NULL,
    CONSTRAINT [PK_SearchGroups] PRIMARY KEY CLUSTERED 
    (
        [StartTime] ASC,
        [SearchWords] ASC
    )
);

Ladda ned SQL-scripten här.

Exempel

Och här är exempeldata

INSERT [dbo].[Searches] ([EventTime], [SearchWords]) 
VALUES
('2013-06-01 08:00:00', 'ssis,etl'),
('2013-06-01 08:25:00', 'etl,ssis'),
('2013-06-01 08:30:00', 'sql,stored,procedure'),
('2013-06-01 08:45:00', 'sql,stored,procedure,debug'),
('2013-06-01 08:55:00', 'ssis,etl'),
('2013-06-01 08:55:00', 'sql,index,clustered'),
('2013-06-01 09:30:00', 'clustered,index,sql');

Med denna exempeldata så skall utresultatet bli

StartTime EndTime NumberOfSearches SearchWords
2013-06-01 08:00 2013-06-01 08:55 3 ssis,etl
2013-06-01 08:30 2013-06-01 08:30 1 sql,stored,procedure
2013-06-01 08:45 2013-06-01 08:45 1 sql,stored,procedure,debug
2013-06-01 08:55 2013-06-01 08:55 1 sql,index,clustered
2013-06-01 09:30 2013-06-01 09:30 1 clustered, index,sql

Problemkonstruktör

Årets tävlingsuppgift är konstruerad av Johan Åhlén.

Utvärdering

Vinnare är det tävlingsbidrag som kan skapa dessa grupperingar med minsta möjliga antal I/O operationer (summan av antal logical reads och logical writes). Om flera bidrag hamnar på nästan exakt samma antal I/O operations används duration som mått för att skilja dem åt. Högsta tillåtna antal tävlingsbidrag per deltagare är tre. Tävlingsbidragen testkörs på en Windows Azure VM Small (1 kärna) med SQL Server 2012 SP1 Web Edition.