Hi Talha,
Thank you for reaching out to us. I see that you’re encountering multiple rows with the same AdGroupId and Id. This is because Age Range Performance Report is a multiple attribution report, which can be thought of as criteria type-specific reports. Thus you may encounter multiple rows with the same AdGroupId and Id. These multiple attribution reports should not be aggregated together, however, as it may double count impressions and clicks. Let me know if you have further questions.
Thank you,
Bryan, Google Ads API Team
{
"id": null,
"selector": {
"fields": [
"AbsoluteTopImpressionPercentage",
"AccentColor",
"AccountCurrencyCode",
"AccountDescriptiveName",
"AccountTimeZone",
"ActiveViewCpm",
"ActiveViewCtr",
"ActiveViewImpressions",
"ActiveViewMeasurability",
"ActiveViewMeasurableCost",
"ActiveViewMeasurableImpressions",
"ActiveViewViewability",
"AdGroupId",
"AdGroupName",
"AdGroupStatus",
"AdStrengthInfo",
"AdType",
"AllConversionRate",
"AllConversionValue",
"AllConversions",
"AllowFlexibleColor",
"Automated",
"AverageCost",
"AverageCpc",
"AverageCpe",
"AverageCpm",
"AverageCpv",
"AveragePageviews",
"AveragePosition",
"AverageTimeOnSite",
"BaseAdGroupId",
"BaseCampaignId",
"BounceRate",
"BusinessName",
"CallOnlyPhoneNumber",
"CallToActionText",
"CampaignId",
"CampaignName",
"CampaignStatus",
"ClickAssistedConversionValue",
"ClickAssistedConversions",
"ClickAssistedConversionsOverLastClickConversions",
"Clicks",
"CombinedApprovalStatus",
"ConversionRate",
"ConversionValue",
"Conversions",
"Cost",
"CostPerAllConversion",
"CostPerConversion",
"CostPerCurrentModelAttributedConversion",
"CreativeDestinationUrl",
"CreativeFinalAppUrls",
"CreativeFinalMobileUrls",
"CreativeFinalUrlSuffix",
"CreativeFinalUrls",
"CreativeTrackingUrlTemplate",
"CreativeUrlCustomParameters",
"CrossDeviceConversions",
"Ctr",
"CurrentModelAttributedConversionValue",
"CurrentModelAttributedConversions",
"CustomerDescriptiveName",
"Description",
"Description1",
"Description2",
"DevicePreference",
"DisplayUrl",
"EngagementRate",
"Engagements",
"EnhancedDisplayCreativeLandscapeLogoImageMediaId",
"EnhancedDisplayCreativeLogoImageMediaId",
"EnhancedDisplayCreativeMarketingImageMediaId",
"EnhancedDisplayCreativeMarketingImageSquareMediaId",
"ExpandedDynamicSearchCreativeDescription2",
"ExpandedTextAdDescription2",
"ExpandedTextAdHeadlinePart3",
"ExternalCustomerId",
"FormatSetting",
"GmailCreativeHeaderImageMediaId",
"GmailCreativeLogoImageMediaId",
"GmailCreativeMarketingImageMediaId",
"GmailForwards",
"GmailSaves",
"GmailSecondaryClicks",
"GmailTeaserBusinessName",
"GmailTeaserDescription",
"GmailTeaserHeadline",
"Headline",
"HeadlinePart1",
"HeadlinePart2",
"Id",
"ImageAdUrl",
"ImageCreativeImageHeight",
"ImageCreativeImageWidth",
"ImageCreativeMimeType",
"ImageCreativeName",
"ImpressionAssistedConversionValue",
"ImpressionAssistedConversions",
"ImpressionAssistedConversionsOverLastClickConversions",
"Impressions",
"InteractionRate",
"InteractionTypes",
"Interactions",
"IsNegative",
"LabelIds",
"Labels",
"LongHeadline",
"MainColor",
"MarketingImageCallToActionText",
"MarketingImageCallToActionTextColor",
"MarketingImageDescription",
"MarketingImageHeadline",
"MultiAssetResponsiveDisplayAdAccentColor",
"MultiAssetResponsiveDisplayAdAllowFlexibleColor",
"MultiAssetResponsiveDisplayAdBusinessName",
"MultiAssetResponsiveDisplayAdCallToActionText",
"MultiAssetResponsiveDisplayAdDescriptions",
"MultiAssetResponsiveDisplayAdDynamicSettingsPricePrefix",
"MultiAssetResponsiveDisplayAdDynamicSettingsPromoText",
"MultiAssetResponsiveDisplayAdFormatSetting",
"MultiAssetResponsiveDisplayAdHeadlines",
"MultiAssetResponsiveDisplayAdLandscapeLogoImages",
"MultiAssetResponsiveDisplayAdLogoImages",
"MultiAssetResponsiveDisplayAdLongHeadline",
"MultiAssetResponsiveDisplayAdMainColor",
"MultiAssetResponsiveDisplayAdMarketingImages",
"MultiAssetResponsiveDisplayAdSquareMarketingImages",
"MultiAssetResponsiveDisplayAdYouTubeVideos",
"Path1",
"Path2",
"PercentNewVisitors",
"PolicySummary",
"PricePrefix",
"PromoText",
"ResponsiveSearchAdDescriptions",
"ResponsiveSearchAdHeadlines",
"ResponsiveSearchAdPath1",
"ResponsiveSearchAdPath2",
"ShortHeadline",
"Status",
"SystemManagedEntitySource",
"TopImpressionPercentage",
"UniversalAppAdDescriptions",
"UniversalAppAdHeadlines",
"UniversalAppAdHtml5MediaBundles",
"UniversalAppAdImages",
"UniversalAppAdMandatoryAdText",
"UniversalAppAdYouTubeVideos",
"ValuePerAllConversion",
"ValuePerConversion",
"ValuePerCurrentModelAttributedConversion",
"VideoQuartile100Rate",
"VideoQuartile25Rate",
"VideoQuartile50Rate",
"VideoQuartile75Rate",
"VideoViewRate",
"VideoViews",
"ViewThroughConversions"
],
"predicates": [],
"dateRange": {
"min": "20200217",
"max": "20200217"
},
"ordering": [],
"paging": null
},
"reportName": "Ad Performance Report",
"reportType": "AD_PERFORMANCE_REPORT",
"dateRangeType": "CUSTOM_DATE",
"downloadFormat": "CSV"
}
Hi Talha,
Thank you for the information and clarification. In your example, the reason Case 2 provides you with two rows for the same AdGroupId and Id combination is because the field IsNegative has two types, “True” and “False”. In this case, your click value of 35 is being bifurcated into the clicks where IsNegative is True or False. This may be the case for some of the attribute types. Let me know if you have further questions.
Hi Talha,
I understand your concern and would like to clarify my previous message. In Ad Performance Report, when you pull an attribute, the report will pull all instances of that attribute that is available. For example, when you query AdGroupId, what you should obtain is every single AdGroupId that is available in the Ad Performance Report under the account you run the query against.
If we apply this to IsNegative, you may encounter some AdGroups that have more than one criterion, in which some are negative (true) and positive (false) that are delimited by the predicate values in the documentation. In this case, you are querying every available criterion and whether the obtained criterion is positive or negative. This isn’t segmenting your data, but rather providing each instance of a positive or negative criterion in your report. Let me know if you have further questions.
Hi Talha,
Thank you for the update. I see two concerns that need to be addressed.
1. Is there a way to know all such attributes for each report which would result in creating multiple rows. How to find such attributes for each report type?
There is no existing list of attributes that would result in creating multiple rows. However, some attributes could produce more than one row if more than one type of attribute exists in that ad group. For example, IsNegative can produce more than one row because there is a chance that your ad group has both negative and positive criterion that exist in the adgroup. However, attributes such as AdGroupStatus cannot be Enabled, Paused, and Disabled at the same time since an AdGroup can only be one status at any given time, therefore it will never provide more than one row.
2. Will this IsNegative cause multiple rows across all the reports where this attribute is valid?
IsNegative may cause multiple rows in some reports where this attribute is a valid attribute if there happens to be an instance where there exists a couple criterion in the same “group” or “campaign” where some are positive and some are negative, in which the report will differentiate the metrics per “positive criteria” and “negative criteria” on the level of the chosen report type.
Greetings!
This was sent over to me because in my 5 years of working on this product, I’ve seen a lot. I have to admit that when I first saw this when I started, I also found it confusing. By the way, kudos on your debugging skills! You noticed that it was isNegative causing you issues; not everyone would notice that.
Since there’s a lot going on here, I’ll explain this in a couple of steps:
I’ll explain what isNegative is doing in this case.
I’ll show you some queries and results to back it up.
I’ll explain what this means in general for all your other queries.
#1
When you look at the definition of isNegative in the report, it says: Indicates if the criterion for this row is a negative (exclusion) criterion.
This means that this field is tied to a criterion. The expectation is that you would never call isNegative without requesting CriterionId because isNegative by itself does not mean anything because you don’t know what isNegative is referring to without the criterion. As a result, isNegative is an attribute tied to the CriterionId segment, which is why it’s labeled as an attribute. The end result is that isNegative appears to implicitly segment when in reality, there’s a mysterious CriterionId that is actually doing the segmenting.
#2
As an engineer, I like to see the code that explains the whole thing. You’re probably the same way, so I’ll show you the queries with their sample results. Please keep in mind that with all these queries, I’ve set includeZeroImpressions to false because I don’t want to be distracted by data with no impressions.
SELECT AdGroupId, Id, Clicks FROM AD_PERFORMANCE_REPORT DURING 20200217,20200217
Everything looks normal with a unique ad group ID and ad ID pair.
SELECT AdGroupId, Id, Clicks, IsNegative FROM AD_PERFORMANCE_REPORT DURING 20200217,20200217
With this one, we see what looks like duplicates. The good news is that the totals are correct. In the next query, you’ll see that they aren’t duplicates. There is a hidden CriterionId doing the segmentation when you called isNegative. In this query, you called a criterion field, so the key is 3 values (AdGropId, Id, and CriterioinId).
SELECT AdGroupId, Id, Clicks, CriterionId, IsNegative FROM AD_PERFORMANCE_REPORT DURING 20200217,20200217
In the last query, I included the CriterionId. As you can see, the key is now 3 values (AdGropId, Id, and CriterioinId). Each row is unique.
#3
Your concern is absolutely valid about other fields being affected. I’ll look into seeing if we can add some warning there in the future for that field. As for other fields, I don’t know of any other field that behaves the same way as this one. You shouldn’t be seeing anything else like this. If you do, please tell us.
I hope that explains the mystery. If you need further clarification, feel free to ask.
Best,
Nadine Wang, Google Ads API Team