Я сделал быстрый запрос, который может помочь.При этом используется функция Pivot, о которой упоминалось ранее.
Вы можете запустить весь процесс или просто перейти к концу!
-- Temp tables
IF OBJECT_ID('tempdb.dbo.#_tmp') IS NOT NULL DROP TABLE #_tmp
IF OBJECT_ID('tempdb.dbo.#_user') IS NOT NULL DROP TABLE #_user
IF OBJECT_ID('tempdb.dbo.#_activity') IS NOT NULL DROP TABLE #_activity
IF OBJECT_ID('tempdb.dbo.#_useractivity') IS NOT NULL DROP TABLE #_useractivity
-- User table
CREATE TABLE #_user (
[USER_ID] INT IDENTITY(1,1) NOT NULL,
[FIRST_NAME] NVARCHAR(50)
)
INSERT INTO #_user ([FIRST_NAME])
VALUES ('John'), ('Peter'), ('Paul')
-- Activity table
CREATE TABLE #_activity (
[ACTIVITY_ID] INT IDENTITY(1,1) NOT NULL,
[ACTIVITY_NAME] NVARCHAR(255)
)
INSERT INTO #_activity ([ACTIVITY_NAME])
VALUES ('Sailing'), ('Bowling'), ('Hiking')
-- Composite table
CREATE TABLE #_useractivity (
[LOG_ID] INT IDENTITY(1,1) NOT NULL,
[USER_ID] INT,
[ACTIVITY_ID] INT
)
INSERT INTO #_useractivity ([USER_ID], [ACTIVITY_ID])
VALUES (1,1),(1,2),(1,3),(1,3),(2,2),(2,3),(3,1), (3,2),(1,2),(2,1)
-- Main data table.
SELECT USR.FIRST_NAME
, A.ACTIVITY_NAME
INTO #_tmp
FROM #_useractivity AS UA
INNER JOIN #_user AS USR ON USR.USER_ID = UA.USER_ID
INNER JOIN #_activity AS A ON A.ACTIVITY_ID = UA.ACTIVITY_ID
SELECT * FROM #_tmp
-- Use pivot function to get desired results.
DECLARE @_cols AS NVARCHAR(MAX)
DECLARE @_sql AS NVARCHAR(MAX)
SET @_cols = STUFF((SELECT ',' + QUOTENAME(T.ACTIVITY_NAME)
FROM #_tmp AS T
GROUP BY T.ACTIVITY_NAME
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,1,'')
-- Trick is to add 1 "counter" before pivoting.
set @_sql = '
SELECT Name, ' + @_cols + '
FROM (
SELECT FIRST_NAME AS Name, ACTIVITY_NAME, 1 AS COUNT
FROM #_tmp
) AS SRC
PIVOT (
SUM(COUNT) FOR ACTIVITY_NAME IN (' + @_cols + ')
) p'
EXEC(@_sql)
Таблица основных данных:
FIRST_NAME ACTIVITY_NAME
John Sailing
John Bowling
John Hiking
John Hiking
Peter Bowling
Peter Hiking
Paul Sailing
Paul Bowling
John Bowling
Peter Sailing
Вывод:
Name Bowling Hiking Sailing
John 2 2 1
Paul 1 NULL 1
Peter 1 1 1