SQL查询计算多列中的外观

时间:2013-07-29 17:15:42

标签: sql sql-server

以下是我的表格示例:

ID     Name     ClickLink1     ClickLink2     ClickLink3
--     ----     ----------     ----------     ----------
1      John     Landing                       ThankYou
2      Abby     ThankYou       Landing        Landing
3      Chris                   ThankYou
4      Sam      Landing        ThankYou       ThankYou

我正在寻找以下结果:

Page       Link         Count
----       ----         -----
Landing    ClickLink1   2
Landing    ClickLink2   1
Landing    ClickLink3   1

最终,我会在“ThankYou”页面的单独报告中重复查询,但我可以轻松复制基于“查询”页面的查询。

使用SQL Server 2008 R2

5 个答案:

答案 0 :(得分:2)

主要问题是您当前的表是非规范化的,因此您需要对列进行计数。实现此目的的一种方法是将多列中的数据拆分为多行。

有几种不同的方法可以做到这一点。您可以使用UNION ALL将列转换为行,然后计算值:

select page, link, count(*) Total
from
(
  select ClickLink1 as page, 'ClickLink1' as link
  from yourtable
  union all
  select ClickLink2 as page, 'ClickLink2' as link
  from yourtable
  union all
  select ClickLink3 as page, 'ClickLink3' as link
  from yourtable
) d
where page = 'Landing'
group by page, link;

SQL Fiddle with Demo。另一种方法是使用CROSS JOIN到虚拟表并计算值:

SELECT page, 
  col as link,
  COUNT(*) AS TOTAL
FROM 
(
  SELECT col, 
    CASE s.col
      WHEN 'ClickLink1' THEN ClickLink1
      WHEN 'ClickLink2' THEN ClickLink2
      WHEN 'ClickLink3' THEN ClickLink3
    END AS page
  FROM yourtable
  CROSS JOIN 
  (
    SELECT 'ClickLink1' AS col UNION ALL 
    SELECT 'ClickLink2' UNION ALL 
    SELECT 'ClickLink3'
  ) s
) s
where page = 'Landing'
group by page, col;

SQL Fiddle with Demo。根据您使用的数据库,您可以使用UNPIVOT函数和聚合来获取结果。例如,如果您使用的是SQL Server,则可以使用:

select page, link, count(*) Total
from yourtable
unpivot
(
  page
  for link in (ClickLink1, ClickLink2, ClickLink3)
) unpiv
where page = 'Landing'
group by page, link;

请参阅SQL Fiddle with Demo

答案 1 :(得分:1)

我认为这样做会在下面进行,并且应该是一个不可知的解决方案,因为你没有提供DBMS风格。

SELECT ClickLink1 as Page, 'ClickLink1' as Link, Count(ID) as Count
FROM myTable
GROUP BY ClickLink1
UNION
SELECT ClickLink2 as Page, 'ClickLink2' as Link, Count(ID) as Count
FROM myTable
GROUP BY ClickLink2
UNION
SELECT ClickLink3 as Page, 'ClickLink3' as Link, Count(ID) as Count
FROM myTable
GROUP BY ClickLink3

答案 2 :(得分:0)

如果你正在使用SQL Server,你可以使用transfer to XML技巧,当我需要将数据转换为EAV时,我会一直使用它,它非常通用且易于维护和更改:

declare @Data xml

select @Data = 
(
    select *
    from test
    for xml raw('Data')
)

;with cte as
(
  select
      T.C.value('.', 'nvarchar(128)') as Page,
      T.C.value('local-name(.)', 'nvarchar(128)') as Link 
  from @Data.nodes('Data/@*') as T(C)
)
select Page, Link, count(*)
from cte
where Page = 'Landing'
group by Page, Link

SQL FIDDLE EXAMPLE

答案 3 :(得分:0)

由于您没有提到您的destination database,我刚刚为您所需的输出创建了一个简单的union all查询。但是,我已经给出了转换工具链接,可以帮助您在目标数据库上转换此查询乐观查询(Oracle,IBM DB2, MySQL, Sybase, PostgreSQL, Informix and Netezza

[转换工具链接1

select ClickLink1 as 'Page', sum(ClickLink1) 'count', 'ClickLink1'
from testtable group by ClickLink1, ClickLink1
union all 
select ClickLink2 as 'Page', sum(ClickLink2) 'count', 'ClickLink2'
from testtable group by ClickLink2,ClickLink2
union all
select ClickLink3 as 'Page', sum(ClickLink3) 'count', 'ClickLink3
from testtable group by ClickLink3

答案 4 :(得分:0)

我认为解决方案无法解决。

create table #a
(
    id int identity,
    Name varchar(500),
    ClickLink1 varchar(500),
    ClickLink2 varchar(500),
    ClickLink3 varchar(500),
)
insert into #a
select 'John','Landing',null,'ThankYou'
union
select 'Abby','ThankYou','Landing','Landing'
union
select 'Chris',null,'ThankYou',null
union
select 'Sam','Landing','ThankYou','ThankYou'

select Name,PAge,COUNT(*) count
from (
    select *
    from #a
)p
UNPIVOT
   (Page FOR clicklink IN 
      (ClickLink1, ClickLink2, ClickLink3)
)AS unpvt
where Page = 'Landing'
group by Name,PAge