473,405 Members | 2,294 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,405 software developers and data experts.

Query: union on self

Hello every body.

I have a small issue.

Problem: I have a table with 4 descriptor columns (type). I need to
formulate a query to retrieve a count for each type so I can group
by...etc. The view I have works, but doesn't work when I supplement the
query with some functions... they just don't like the UNION. The real
problem is I can't change any of the udf's or queries, just the view.
The view is inner joined back on to the primary table 'qt_ins' again
and a heap of other tables. But for this post and to not complicate it
too much I've just included the primary table and the view...
Also my querys work if I don't put a where clause on for the VIEW. eg:
.... and cv.type = 'Environmental'.... for some reason with a clause it
gets stuck in an *infinite loop.
Conditions: The table structure cannot be changed in anyway. The
view/query must return 2 columns qi_id & type.

I considered creating a function to return the Types but then I figured
I would ask you folks for a better way.

Any help with the view appreciated.

Thank you.

The below will create the table, with sample data and the view.

---------------------------Start
Query--------------------------------------------
CREATE TABLE [dbo].[qt_ins] (
[qi_id] [int] NOT NULL ,
[qi_injury] [bit] NULL ,
[qi_environmental] [bit] NULL ,
[qi_equipment_damage] [bit] NULL ,
[qi_vehicle] [bit] NULL
) ON [PRIMARY]
GO

INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (20,1,0,0,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (21,0,1,0,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (23,1,0,0,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (24,1,0,0,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (25,1,1,1,1)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (26,1,0,0,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (27,1,0,0,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (28,1,0,0,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (29,1,0,0,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (30,1,1,1,1)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (31,1,0,0,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (32,1,1,1,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (33,1,0,0,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (34,1,1,1,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (35,1,0,0,1)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (36,1,0,0,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (37,0,0,0,1)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (38,0,0,0,1)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (39,0,1,0,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (40,1,0,0,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (41,0,0,0,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (42,1,0,0,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (43,1,0,0,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (44,0,1,1,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (45,1,0,0,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (46,1,0,0,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (47,1,0,0,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (48,1,0,0,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (49,1,0,0,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (50,1,0,1,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (51,0,0,1,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (52,0,1,0,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (53,1,0,0,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (54,1,0,0,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (55,1,0,0,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (56,1,1,1,1)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (57,1,0,0,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (58,1,0,0,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (59,0,1,0,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (60,0,1,0,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (61,1,0,0,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (62,0,1,0,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (63,1,0,0,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (64,1,0,0,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (65,1,0,1,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (66,1,0,0,1)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (67,1,1,1,1)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (68,1,0,0,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (69,1,0,0,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (70,1,1,1,1)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (71,1,1,1,1)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (72,1,1,1,1)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (73,0,0,1,0)
INSERT INTO qt_ins
(qi_id,qi_injury,qi_environmental,qi_equipment_dam age,qi_vehicle)
VALUES (81,1,0,0,0)
GO
CREATE VIEW dbo.v_qt_in_type
AS
SELECT qi_id, 'Injury' AS type FROM qt_ins WHERE qi_injury = 1
UNION all
SELECT qi_id, 'Environmental' AS type FROM qt_ins WHERE
qi_environmental = 1
UNION all
SELECT qi_id, 'Equipment damage' AS type FROM qt_ins WHERE
qi_equipment_damage = 1
UNION all
SELECT qi_id, 'Vehicle' AS type FROM qt_ins WHERE qi_vehicle = 1
GO

select count(*),type from v_qt_in_type group by type
---------------------------END
QUERY--------------------------------------

Jul 10 '06 #1
7 3288
KoliPoki (ra****@gmail.com) writes:
Problem: I have a table with 4 descriptor columns (type). I need to
formulate a query to retrieve a count for each type so I can group
by...etc. The view I have works, but doesn't work when I supplement the
query with some functions... they just don't like the UNION. The real
problem is I can't change any of the udf's or queries, just the view.
The view is inner joined back on to the primary table 'qt_ins' again
and a heap of other tables. But for this post and to not complicate it
too much I've just included the primary table and the view...
Also my querys work if I don't put a where clause on for the VIEW. eg:
... and cv.type = 'Environmental'.... for some reason with a clause it
gets stuck in an *infinite loop.
I'm afraid that it's impossible to assist with the information you have
given. First you say "don't like the UNION", which indicates that you
have some trivial syntax error. Then you talk about infinite loops,
which indicates that the query runs for a very long time.

You posted a repro, which is great. Unfortunately, that repro appears to
work without any problems. If you instead post a repro that demonstrates
the problem, it's a lot easier to say what is going on.

--
Erland Sommarskog, SQL Server MVP, es****@sommarskog.se

Books Online for SQL Server 2005 at
http://www.microsoft.com/technet/pro...ads/books.mspx
Books Online for SQL Server 2000 at
http://www.microsoft.com/sql/prodinf...ons/books.mspx
Jul 10 '06 #2
Erland, thank you for your reply.

That's correct the UNION doesn't work with my query.
Unfortunately it's very hard to give you all the code as there are 3
functions and another 12 tables, 2 with hierarchical
(parent/child/lineage) data (Business units, Job titles).

There are no syntax errors, the problem is that my query never
returns... like it's stuck in a loop. If I remove the union like:
-----------------------------------------------
CREATE VIEW dbo.v_qt_in_type
AS
SELECT qi_id, 'Environmental' AS type FROM qt_ins WHERE
qi_environmental = 1
-------------------------------------------------
it works fine and fast, but is obviously incorrect as it only returns
records of 1 type.
So the problem is....

Can any one think of another way to write the below query without the
UNION

---------------Query to write in a different way---------------

SELECT qi_id, 'Injury' AS type FROM qt_ins WHERE qi_injury = 1
UNION all
SELECT qi_id, 'Environmental' AS type FROM qt_ins WHERE
qi_environmental = 1
UNION all
SELECT qi_id, 'Equipment damage' AS type FROM qt_ins WHERE
qi_equipment_damage = 1
UNION all
SELECT qi_id, 'Vehicle' AS type FROM qt_ins WHERE qi_vehicle = 1

------------------------END QUERY-------------------------------------

Thanks for your help, and apologies for not being able to provider the
full context of the issue.

R.

Erland Sommarskog wrote:
KoliPoki (ra****@gmail.com) writes:
Problem: I have a table with 4 descriptor columns (type). I need to
formulate a query to retrieve a count for each type so I can group
by...etc. The view I have works, but doesn't work when I supplement the
query with some functions... they just don't like the UNION. The real
problem is I can't change any of the udf's or queries, just the view.
The view is inner joined back on to the primary table 'qt_ins' again
and a heap of other tables. But for this post and to not complicate it
too much I've just included the primary table and the view...
Also my querys work if I don't put a where clause on for the VIEW. eg:
... and cv.type = 'Environmental'.... for some reason with a clause it
gets stuck in an *infinite loop.

I'm afraid that it's impossible to assist with the information you have
given. First you say "don't like the UNION", which indicates that you
have some trivial syntax error. Then you talk about infinite loops,
which indicates that the query runs for a very long time.

You posted a repro, which is great. Unfortunately, that repro appears to
work without any problems. If you instead post a repro that demonstrates
the problem, it's a lot easier to say what is going on.

--
Erland Sommarskog, SQL Server MVP, es****@sommarskog.se

Books Online for SQL Server 2005 at
http://www.microsoft.com/technet/pro...ads/books.mspx
Books Online for SQL Server 2000 at
http://www.microsoft.com/sql/prodinf...ons/books.mspx
Jul 10 '06 #3
You can try something like this:

SELECT qi_id,
case
when qi_injury = 1 then 'Injury'
when qi_environmental = 1 then 'environmental'
when qi_Equipment damage = 1 then 'Equipment damage'
when qi_Vehicle = 1 then 'Vehicle'
end
AS type
FROM qt_ins
WHERE (qi_injury = 1) or (qi_environmental = 1 ) or
(qi_equipment_damage = 1)
or (qi_vehicle = 1)

But it would be interesting to see why is your original query slow. Any
additional infotrmation?

Jul 11 '06 #4
KoliPoki wrote:
Erland, thank you for your reply.

That's correct the UNION doesn't work with my query.
Unfortunately it's very hard to give you all the code as there are 3
functions and another 12 tables, 2 with hierarchical
(parent/child/lineage) data (Business units, Job titles).

There are no syntax errors, the problem is that my query never
returns... like it's stuck in a loop. If I remove the union like:
-----------------------------------------------
CREATE VIEW dbo.v_qt_in_type
AS
SELECT qi_id, 'Environmental' AS type FROM qt_ins WHERE
qi_environmental = 1
-------------------------------------------------
it works fine and fast, but is obviously incorrect as it only returns
records of 1 type.
So the problem is....

Can any one think of another way to write the below query without the
UNION

---------------Query to write in a different way---------------

SELECT qi_id, 'Injury' AS type FROM qt_ins WHERE qi_injury = 1
UNION all
SELECT qi_id, 'Environmental' AS type FROM qt_ins WHERE
qi_environmental = 1
UNION all
SELECT qi_id, 'Equipment damage' AS type FROM qt_ins WHERE
qi_equipment_damage = 1
UNION all
SELECT qi_id, 'Vehicle' AS type FROM qt_ins WHERE qi_vehicle = 1

------------------------END QUERY-------------------------------------

Thanks for your help, and apologies for not being able to provider the
full context of the issue.
Alexander has given what I think is a pretty good solution to this. To
the original problem though, did you get a query plan for the select
statement that ran for so long? What was the query plan doing?

One thing to keep in mind is that if you are using UDFs, they can often
dramatically impact a querie's performance. It's impossible to know
without your data and the full table, UDF, and view SQL code, but maybe
when you use the UNION with the UDF it has to actually select the
entire dataset, applying the UDF to each row and then performing the
UNION operations before it is able to filter out rows based on your
WHERE clause criteria. I'm afraid that I don't know how smart SQL
Server is when you do a union like this within a view and then select
from the view based on a column that is calculated within the view.
Even if the UDF has nothing to do with it, it may be that when you
select WHERE qi_environmental = 1 then SQL Server can use an index, but
when you have a column hard-coded the way that you do in the unions it
can no longer use that index when you do WHERE type = 'Environmental'.

Anyway, just some stuff to look into for you.

-Tom.

Jul 11 '06 #5
Alexander Kuznetsov wrote:
You can try something like this:

SELECT qi_id,
case
when qi_injury = 1 then 'Injury'
when qi_environmental = 1 then 'environmental'
when qi_Equipment damage = 1 then 'Equipment damage'
when qi_Vehicle = 1 then 'Vehicle'
end
AS type
FROM qt_ins
WHERE (qi_injury = 1) or (qi_environmental = 1 ) or
(qi_equipment_damage = 1)
or (qi_vehicle = 1)

But it would be interesting to see why is your original query slow. Any
additional infotrmation?
I just posted that this was a good solution in another post, but now it
occurs to me that it will not return the same resultset as the original
poster's solution. The query above will return only one row per qi_id,
but the original solution could return up to four for each qi_id.

-Tom.

Jul 11 '06 #6
Thomas,

thanks for the correction. Untested again, no DDL, no DML!

SELECT qi_id, t.c AS type
FROM qt_ins join
(
select 1 n, 'Injury' c
union all
select 2 n, 'environmental' c
union all
select 3 n, 'Equipment damage' c
union all
select 4 n, 'Vehicle' c
) t
on (qi_injury = 1 and t.n=1) or (qi_environmental = 1 and t.n=2) or
(qi_equipment_damage = 1 and t.n=3)
or (qi_vehicle = 1 and t.n=4)

Jul 11 '06 #7
Thanks Folks.

I was dubious of using a derived table, as I had already tried wrapping
some of the logic in derived table and it didn't work, but I never
tried using a derived table for the view...guess what, it work!

Why, I'm still not sure.

The query was never returning when the view and a function were used in
the clause of the query.

Example of not working:
select qi_id, .....
from qt_ins q
inner join v_qt_in_type v on q.qu_id = v.qi_id
inner join ...
inner join ...
....
where
..... and
q.qi_mr_emp_no in(select emp_no from udf_qi_my_subordinates('49549'))
and
q.qi_observation_date>=dateadd(yy,-1,current_timestamp) and
v.type = 'Environmental' and
dbo.udf_qi_em_return_above_reportsto2_1(q.qi_mr_em p_no,'49549') = 'GM
OH&S'
But would return if either
dbo.udf_qi_em_return_above_reportsto2_1(q.qi_mr_em p_no,'49549') = 'GM
OH&S' or v.type = 'Environmental' was removed it would work even if
they were referenced the select string.

Example working:
select qi_id, .....
from qt_ins q
inner join v_qt_in_type v on q.qu_id = v.qi_id
inner join ...
inner join ...
....
where
..... and
q.qi_mr_emp_no in(select emp_no from udf_qi_my_subordinates('49549'))
and
q.qi_observation_date>=dateadd(yy,-1,current_timestamp) and
--v.type = 'Environmental' and
dbo.udf_qi_em_return_above_reportsto2_1(q.qi_mr_em p_no,'49549') = 'GM
OH&S'

Thanks Alexander for your help.
Alexander Kuznetsov wrote:
Thomas,

thanks for the correction. Untested again, no DDL, no DML!

SELECT qi_id, t.c AS type
FROM qt_ins join
(
select 1 n, 'Injury' c
union all
select 2 n, 'environmental' c
union all
select 3 n, 'Equipment damage' c
union all
select 4 n, 'Vehicle' c
) t
on (qi_injury = 1 and t.n=1) or (qi_environmental = 1 and t.n=2) or
(qi_equipment_damage = 1 and t.n=3)
or (qi_vehicle = 1 and t.n=4)
Jul 12 '06 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: Wiebke Pätzold | last post by:
import sys Hi all, At the beginning there is a table (database) with different columns. So I create a search operator to look for regular expressions. First I start the search only in one...
4
by: techquest | last post by:
got slightly similar table. #Temp Table: name,name1,name2,exam,score A,A1,A21, A,A1,A21,math100,88 A,A1,A21,math101,56 A,A1,A21, A,A1,A21,math102,67 A,A1,A21, A,A1,A21,math104,45
3
by: Paradigm | last post by:
I am using Access 2K as a front end to a MYSQL database. I am trying to run a Union query on the MYSQL database. The query is (much simplified) SELECT as ID from faxdata UNION SELECT as ID ...
3
by: Richard Williamson | last post by:
Hi all, I have managed, using a quite tortuous route, to select certain records in a UNION query. This is based on the results of other queries. Question: how the devil do I change the value...
2
by: sumit.sharma | last post by:
Hi, I have some experience in C prog language. I have small doubt abt using unions in C language. I have the foll. union union MyUnion { char name ;
2
by: MLH | last post by:
Fields in MyTable: PostID PostDate RollQtyXfer RollDenomination RollCount37 RollCount23
4
by: Stan | last post by:
I am running in ACCESS 2003 a database with a single table. It records service rendered to clients of a food pantry. As each client is served the date is entered into 1-6 fields SvcDate1,...
5
by: wugon.net | last post by:
question: db2 LUW V8 UNION ALL with table function month() have bad query performance Env: db2 LUW V8 + FP14 Problem : We have history data from 2005/01/01 ~ 2007/05/xx in single big...
4
by: bobdydd | last post by:
Hi All I have a query based on a single Table the has the following fields: Field 1: BoughtDate Field 2: SoldDate Sometimes the SoldDate is earlier than the BoughtDate What I am trying to...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.