Reputation: 1241
Here is an example of my table:
ID Name ClickLink1 ClickLink2 ClickLink3
-- ---- ---------- ---------- ----------
1 John Landing ThankYou
2 Abby ThankYou Landing Landing
3 Chris ThankYou
4 Sam Landing ThankYou ThankYou
I'm looking for results such as:
Page Link Count
---- ---- -----
Landing ClickLink1 2
Landing ClickLink2 1
Landing ClickLink3 1
Ultimately I will repeat the query in a separate report for the "ThankYou" page, but I can easily duplicate based off query for "Landing" page.
Using SQL Server 2008 R2
Upvotes: 0
Views: 467
Reputation: 6881
I think this would do it below, and should be an agnostic solution since you didn't provide the DBMS flavor.
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
Upvotes: 1
Reputation: 1091
I think the solution is un pivot.
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
Upvotes: 0
Reputation: 2673
As you didn't mentioned that your destination database
, I just created a simple union all
query for your required output. However, I've given the conversion tool link which helps you to convert this query on the destination databases optimistic query(Oracle,IBM DB2, MySQL, Sybase, PostgreSQL, Informix and Netezza
)
[Conversion Tool Link1
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
Upvotes: 0
Reputation: 247680
The main issue is that your current table is denormalized so you need to count across the columns. One way to do this would be to unpivot the data from multiple columns into multiple rows.
There are a few different ways that you can do this. You can use a UNION ALL to converts the columns into rows and then count the values:
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;
See SQL Fiddle with Demo. Another way would be to use a CROSS JOIN to a virtual table and count the values:
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;
See SQL Fiddle with Demo. Depending on your database that you are using you might be able to use an UNPIVOT function along with the aggregate to get the result. For example, if you are using SQL Server you can use:
select page, link, count(*) Total
from yourtable
unpivot
(
page
for link in (ClickLink1, ClickLink2, ClickLink3)
) unpiv
where page = 'Landing'
group by page, link;
Upvotes: 2
Reputation: 117370
If you're using SQL Server, you can use transfer to XML trick, which I use all the time when I need to transform data to EAV, it's very general and easy to maintain and change:
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
Upvotes: 0