en-USsv-SE
You are here:   Forum
HomeHomeSQLug.SESQLug.SETävlingarTävlingarSQLug.se challenge 2011SQLug.se challenge 2011
Previous
 
Next
New Post
5/26/2011 5:00 PM
 
Hej igen !

Här kommer mitt sista bidrag, GR18.

Mvh/
Göran Rönnbäck, SQL Service.

1. Setup

CREATE NONCLUSTERED INDEX [IX_PeopleAttribute_ID_Value] ON [dbo].[PeopleAttribute]

(

[AttributeID] ASC,

[AttributeValue] ASC

)

INCLUDE ( [PeopleID]) WITH (PAD_INDEX = ON, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 100) ON [PRIMARY]

GO

CREATE NONCLUSTERED INDEX [IX_WantedAttribute_ID_Value] ON [dbo].[WantedAttribute]

(

[AttributeID] ASC,

[AttributeValue] ASC

)

INCLUDE ( [WantedSetID]) WITH (PAD_INDEX = ON, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 100) ON [PRIMARY]

GO

CREATE VIEW [dbo].[qryWantedPeople18]

WITH SCHEMABINDING

AS

SELECT w.WantedSetID, p.PeopleID, COUNT(*) AS qryWantedPeople_Count

FROM dbo.WantedAttribute w (TABLOCK)

CROSS APPLY (

SELECT PeopleID

FROM dbo.PeopleAttribute (TABLOCK)

WHERE w.AttributeID = AttributeID

AND w.AttributeValue = AttributeValue

-- AND ASCII(w.AttributeValue) = ASCII(AttributeValue)

) AS p

GROUP BY w.WantedSetID, p.PeopleID

GO

CREATE PROCEDURE [dbo].[SQLUG_GetRows_GR18]

AS

/*

DBCC DROPCLEANBUFFERS

DBCC FREEPROCCACHE

 

EXEC [dbo].[SQLUG_GetRows_GR18]

*/

SET NOCOUNT ON

 

SELECT People.PeopleID, People.WantedSetID

FROM qryWantedPeople15 People (TABLOCK)

WHERE People.qryWantedPeople_Count =

(

SELECT COUNT(*) AS Count_WantedSetID

FROM [dbo].[WantedAttribute] Wanted (TABLOCK)

WHERE Wanted.WantedSetID = People.WantedSetID

GROUP BY [WantedSetID]

)

OPTION (LOOP JOIN, MAXDOP 0);

GO

2. Exekveringsdel

EXEC [dbo].[SQLUG_GetRows_GR18]

 

3. Cleanup

IF EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[PeopleAttribute]') AND name = N'IX_PeopleAttribute_ID_Value')

DROP INDEX [IX_PeopleAttribute_ID_Value] ON [dbo].[PeopleAttribute] WITH ( ONLINE = OFF )

GO

IF EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[WantedAttribute]') AND name = N'IX_WantedAttribute_ID_Value')

DROP INDEX [IX_WantedAttribute_ID_Value] ON [dbo].[WantedAttribute] WITH ( ONLINE = OFF )

GO

IF EXISTS (SELECT * FROM sys.views WHERE object_id = OBJECT_ID(N'[dbo].[qryWantedPeople18]'))

DROP VIEW [dbo].[qryWantedPeople18]

GO

IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[SQLUG_GetRows_GR18]') AND type in (N'P', N'PC'))

DROP PROCEDURE [dbo].[SQLUG_GetRows_GR18]

GO

 
New Post
5/26/2011 6:39 PM
 
Mitt andra förslag, men den presterar inte så bra om man har djupa wantedSets:

DECLARE @MaxWantedSetID INT
 SELECT @MaxWantedSetID=MAX(WantedSetID) FROM WantedAttribute

 CREATE TABLE #Wantedranked (WantedSetID TINYINT NOT NULL,
                             AttributeID TINYINT NOT NULL,
                             AttributeValue CHAR(1) COLLATE Finnish_Swedish_CI_AS NOT NULL ,
                             WantedRnInSet INT NOT NULL,
                             MaxWantedRnInSet INT NOT NULL)
 -- create index later
 
 CREATE TABLE #ResultTable (PeopleID INT NOT NULL,
                            WantedSetID TINYINT NOT NULL)
 -- no indexes required
 
 
 CREATE TABLE #MatchedBefore (PeopleID INT NOT NULL,
                            WantedSetID TINYINT NOT NULL
                            )

-- insert and update Wantedranked
 INSERT INTO #Wantedranked(WantedSetID, AttributeID, AttributeValue, wantedRnInSet, MaxWantedRnInSet)
    SELECT  WantedSetID, AttributeID, AttributeValue,
            wantedRnInSet=ROW_NUMBER() OVER(PARTITION BY WantedSetID    ORDER BY AttributeID),
            MaxWantedRnInSet=1    -- dummy value
    FROM WantedAttribute

 CREATE UNIQUE NONCLUSTERED INDEX IX_ttWantedranked_wantedRnInSet_MaxWantedRnInSet_AttributeID_AttributeValue_WantedSetID
    ON #Wantedranked (wantedRnInSet, MaxWantedRnInSet, AttributeID, AttributeValue, WantedSetID)
    WITH (FILLFACTOR=100)
 CREATE NONCLUSTERED INDEX IX_ttWantedranked_WantedSetID        -- used for update
    ON #Wantedranked (WantedSetID)
    WITH (FILLFACTOR=100)
    
 UPDATE uwr
 SET MaxWantedRnInSet=t.MaxWantedRnInSet
 FROM #Wantedranked AS uwr
  INNER JOIN (    SELECT DISTINCT WantedSetID, MaxWantedRnInSet=MAX(WantedRnInSet) OVER(PARTITION BY WantedSetID)
                FROM #Wantedranked
                ) AS t ON t.WantedSetID=uwr.WantedSetID

-- set root to following loop, for level 1 fill #ResultTable and #MatchedBefore

INSERT INTO #ResultTable(PeopleID,WantedSetID)
 SELECT pa.PeopleID, wr.WantedSetID
 FROM #Wantedranked wr
 INNER JOIN PeopleAttribute pa    ON pa.AttributeID=wr.AttributeID
                                AND pa.AttributeValue=wr.AttributeValue
 WHERE wr.WantedRnInSet=wr.MaxWantedRnInSet                        -- done
 AND wr.wantedRnInSet=1    

INSERT INTO #MatchedBefore(PeopleID, WantedSetID)
    SELECT pa.PeopleID, wr.WantedSetID
    FROM #Wantedranked wr
    INNER JOIN PeopleAttribute pa    ON pa.AttributeID=wr.AttributeID
                                    AND pa.AttributeValue=wr.AttributeValue
    WHERE wr.WantedRnInSet<wr.MaxWantedRnInSet                        -- not done yet
    AND wr.wantedRnInSet=1

DECLARE @rowcount INT=1,
        @i TINYINT=1;
-- loop here
 WHILE (@i<=@MaxWantedSetID AND EXISTS (SELECT NULL FROM #MatchedBefore))
  BEGIN    
    IF @i>1
        -- delete all that are not matched on next level
        DELETE FROM #MatchedBefore
        FROM #MatchedBefore AS pl
        LEFT JOIN
            (-- find matches
            #Wantedranked wr
            INNER JOIN PeopleAttribute pa    ON pa.AttributeID=wr.AttributeID
                                            AND pa.AttributeValue=wr.AttributeValue
                                            AND wr.WantedRnInSet<wr.MaxWantedRnInSet        -- not done yet
                                            AND wr.wantedRnInSet=@i
            ) ON wr.WantedSetID=pl.WantedSetID
              AND pa.PeopleID=pl.PeopleID
        WHERE wr.WantedSetID IS NULL

    SELECT @i=@i+1    
      
    INSERT INTO #ResultTable(PeopleID,WantedSetID)
        SELECT pa.PeopleID, wr.WantedSetID
        FROM #Wantedranked wr
        INNER JOIN PeopleAttribute pa    ON pa.AttributeID=wr.AttributeID
                                        AND pa.AttributeValue=wr.AttributeValue
                                        AND wr.WantedRnInSet=wr.MaxWantedRnInSet                        -- done
                                        AND wr.wantedRnInSet=@i
        -- only those that matched before
        INNER JOIN #MatchedBefore pl ON pl.PeopleID=pa.PeopleID            
                                        AND pl.WantedSetID=wr.WantedSetID
                                        

  END -- while

 SELECT  * FROM    #ResultTable

 DROP TABLE #MatchedBefore
 DROP TABLE #ResultTable
 DROP TABLE #Wantedranked

----------------------------------------------- end of code
 
New Post
5/26/2011 8:52 PM
 
Hej igen!!!
Jag var tvungen att, efter en härlig dag på Microsoft, trimma lösningen en sista gång.

Den skiljer inte sig nåt mycket från min förra men jag fick ner reads. Hoppas på lite tur...
Hälsningar till er alla,
Jesús


-- SETUP
if exists (select * from sys.views where object_id = object_id(N'dbo.WantedAttributeGrouped04'))
drop view dbo.WantedAttributeGrouped04
GO
create view dbo.WantedAttributeGrouped04
as
select
WantedSetID
,count(WantedSetID) as RowsInGroup
from
dbo.WantedAttribute
where
WantedAttributeID > 0
group by
WantedSetID
GO


if exists (select * from sys.views where object_id = object_id(N'dbo.WantedPeopleGrouped04'))
drop view dbo.WantedPeopleGrouped04
GO
create view dbo.WantedPeopleGrouped04
as
select
PeopleID
,count(PeopleID) as RowsInGroup
from
dbo.PeopleAttribute
where
PeopleAttributeID > 0
group by
PeopleID
GO


if exists (select * from sys.views where object_id = object_id(N'dbo.PeopleAttributeView04'))
drop view dbo.PeopleAttributeView04
GO
create view dbo.PeopleAttributeView04
as
select
PeopleID
,AttributeID
,AttributeValue
from
dbo.PeopleAttribute
where
PeopleAttributeID > 0
group by
PeopleID
,AttributeID
,AttributeValue
GO


if exists (select * from sys.views where object_id = object_id(N'dbo.WantedAttributeView04'))
drop view dbo.WantedAttributeView04
GO
create view dbo.WantedAttributeView04
as
select
WantedSetID
,AttributeID
,AttributeValue
from
dbo.WantedAttribute
where
WantedAttributeID > 0
group by
AttributeID
,WantedSetID
,AttributeValue
GO


if exists (select * from sys.objects where object_id = object_id(N'dbo.SearchPeopleMatches04') and type in (N'P', N'PC'))
drop procedure dbo.SearchPeopleMatches04
GO
create procedure dbo.SearchPeopleMatches04
as
begin
set nocount on

select
pl.PeopleID
,al.WantedSetID
from
(
select
g.PeopleID
,AttributeID
,AttributeValue
,g.RowsInGroup
from
dbo.PeopleAttributeView04 pav
join
dbo.WantedPeopleGrouped04 g
on
g.PeopleID = pav.PeopleID
) pl
join
(
select
g.WantedSetID
,AttributeID
,AttributeValue
,g.RowsInGroup
from
dbo.WantedAttributeView04 wav
join
dbo.WantedAttributeGrouped04 g
on
g.WantedSetID = wav.WantedSetID
) al
on
al.AttributeID = pl.AttributeID
where
al.AttributeValue = pl.AttributeValue
group by
pl.PeopleID
,al.WantedSetID
,al.RowsInGroup
,pl.RowsInGroup
having
pl.RowsInGroup >= al.RowsInGroup
order by
pl.PeopleID
,al.WantedSetID
end
GO





-- MAIN
exec dbo.SearchPeopleMatches04




-- CLEANUP
if exists (select * from sys.views where object_id = object_id(N'dbo.WantedAttributeGrouped04'))
drop view dbo.WantedAttributeGrouped04
GO

if exists (select * from sys.views where object_id = object_id(N'dbo.WantedPeopleGrouped04'))
drop view dbo.WantedPeopleGrouped04
GO

if exists (select * from sys.views where object_id = object_id(N'dbo.PeopleAttributeView04'))
drop view dbo.PeopleAttributeView04
GO

if exists (select * from sys.views where object_id = object_id(N'dbo.WantedAttributeView04'))
drop view dbo.WantedAttributeView04
GO

if exists (select * from sys.objects where object_id = object_id(N'dbo.SearchPeopleMatches04') and type in (N'P', N'PC'))
drop procedure dbo.SearchPeopleMatches04
GO
 
New Post
5/26/2011 9:56 PM
 
---------------------------------------
---- Author: Henrik Nilsson
---- Company: Brummer & Partners
---- Edition: 3
---- Version: 1
-------------------------------------

-- Setup
SET NOCOUNT ON
CREATE NONCLUSTERED INDEX IX_HN ON dbo.PeopleAttribute (AttributeID ASC, AttributeValue ASC) INCLUDE (PeopleID) WITH (FILLFACTOR = 100) ON [PRIMARY]
GO

-- Main Run
SELECT derTab1.PeopleID
,derTab1.WantedSetID
FROM (
SELECT wa.WantedSetID
,pa.PeopleID
,COUNT(*) AS NumberOfWantedAttributes
FROM dbo.WantedAttribute AS wa
INNER JOIN dbo.PeopleAttribute AS pa WITH (FORCESEEK) ON 1 = 1
AND pa.AttributeID = wa.AttributeID
AND pa.AttributeValue = wa.AttributeValue
GROUP BY wa.WantedSetID
,pa.PeopleID
) AS derTab1
WHERE EXISTS (
SELECT *
FROM dbo.WantedAttribute AS w
WHERE w.WantedSetID = derTab1.WantedSetID
GROUP BY w.WantedSetID
HAVING COUNT(*) = derTab1.NumberOfWantedAttributes
)

-- Cleanup
DROP INDEX IX_HN ON dbo.PeopleAttribute
SET NOCOUNT OFF
GO
 
New Post
5/26/2011 10:14 PM
 
Tävlingen avslutad!



Tack för det stora intresset och alla tävlingsbidrag som kommit in. Nu kommer vi att göra ytterligare en genomgång av bidragen och fastställa resultaten.



Vinnaren av denna tävling kommer att meddelas och presenteras på vår träff den 31/5 i Stockholm. Då kommer vi också att synliggöra alla tävlingsbidrag på detta forum.



 
Previous
 
Next
HomeHomeSQLug.SESQLug.SETävlingarTävlingarSQLug.se challenge 2011SQLug.se challenge 2011


Annons