2013-11-14 2 views
1

У меня есть user_log_table, который имеет столбцыдинамически генерируемые заголовки столбцов в SQL запросе

Userid   logintime    browsername 
    1  2013/10/01 00:10:10   Chrome 
    1  2013/10/01 17:23:10   Chrome 
    1  2013/10/01 00:30:41   Mozilla 
    1  2013/10/02 05:10:52   IE 
    3  2013/10/02 09:10:25   Chrome 
    3  2013/10/03 10:10:18   Safari 
    1  2013/10/03 13:10:35   Chrome 

Я хочу, чтобы запрос, который должен отображать вывод как

Userid browser 01/10 02/10 03/10 
    1  Chrome  2  0  1 
    1  Mozilla 1  0  0 
    1  IE   0  1  0 
    3  Chrome  0  1  0 
    3  Safari  0  0  1 

Пожалуйста, обратите внимание, что Browsername не неподвижная его динамика, ...

Я попытался с запросом в

SELECT userid, browser, Day(logintime) as LoginDay, COUNT(logintime) as Num 
FROM user_log_table 
GROUP BY userid, browser, Day(logintime) 

, но не нашел результат, как я хочу. Могу ли я получить колонку, как указано выше, и данные тоже?

ответ

2

Я видел это динамическая задача поворота разное время. И у меня это было. После долгих поисков я пришел к решению, которое отлично работает для меня. это не так элегантно, но это спасло меня. Сначала я готовлю данные во временную таблицу, после чего динамически создаю сводную строку (в вашем случае это DD-MM), назначая ее переменной. И, в конце концов, я строю строку sql для выполнения как динамический sql.

Я использовал ваши данные образца и, похоже, работает. Надеюсь, что это помогает

select 
    userid, 
     browsername, 
     CAST(day(logintime) as nvarchar(2)) + '-' + CAST(Month(logintime) AS nVARCHAR(2)) AS period 
INTO #TMP 
from user_log_table order by 1 

DECLARE @cols AS NVARCHAR(MAX), @query AS NVARCHAR(MAX) 
select @cols = STUFF((SELECT distinct ',' 
        + QUOTENAME(convert(varchar(10), period, 120)) 
       from #TMP order by 1 
     FOR XML PATH(''), TYPE 
     ).value('.', 'NVARCHAR(MAX)') 
    ,1,1,'') 

set @query = 'SELECT userid, browsername,' + @cols + ' from 
     (
      select userid, browsername, period 
      from #TMP 
     ) x 
     pivot 
     (
      count(period) 
      for period in (' + @cols + ') 
     ) p ' 
exec(@query) 
drop table #TMP 
1

-то вроде следующего, или вы можете использовать это с PIVOT в MS SQL:

SQLFiddle demo

SELECT browsername, 
     SUM(CASE WHEN DAY(logintime) = 1 THEN 1 ELSE 0 END) as [01/10], 
     SUM(CASE WHEN DAY(logintime) = 2 THEN 1 ELSE 0 END) as [02/10], 
     SUM(CASE WHEN DAY(logintime) = 3 THEN 1 ELSE 0 END) as [03/10], 
     ... 
     SUM(CASE WHEN DAY(logintime) = 31 THEN 1 ELSE 0 END) as [31/10] 

FROM user_log_table 
GROUP BY browsername 
+0

Он работает, но SUM (CASE КОГДА ДЕНЬ (logintime) = 1 THEN 1 ELSE 0 END), как [01/10] заявления должны быть dynamic..I значит, если Месяц февраль тогда наступит 28 дней ... вот так .. –

0
DECLARE @cols VARCHAR(100),@SQL VARCHAR(MAX) 
select @cols = STUFF((SELECT distinct ',' + 
         QUOTENAME(convert(varchar(10),LoginTime,103)) 
         FROM 
         user_log_table 
         FOR XML PATH(''), TYPE 
        ).value('.', 'NVARCHAR(MAX)') 
         , 1, 1, ''); 
SET @SQL = 'SELECT * 
FROM 
(
    SELECT 
    Userid, 
    browsername, 
    convert(varchar(10),LoginTime,103) LoginDay 
    FROM user_log_table xx 
) AS t 
PIVOT 
(
    count(LoginDay) 
    FOR LoginDay IN('[email protected]+')) AS p ; ' 

    EXEC (@SQL)  
Смежные вопросы