วิธีอัปโหลดข้อมูลดิบจาก Google Ads ไปยัง Google BigQuery
เผยแพร่แล้ว: 2022-04-12ด้วยการวิเคราะห์ประสิทธิภาพของแคมเปญโฆษณา Google Ads ใน Google Analytics คุณอาจพบการสุ่มตัวอย่าง การรวมข้อมูล หรือข้อจำกัดอื่นๆ ของอินเทอร์เฟซระบบ โชคดีที่ปัญหานี้แก้ไขได้ง่ายๆ ด้วยการอัปโหลดข้อมูลดิบจากบริการโฆษณาของคุณไปยัง Google BigQuery
ในบทความนี้ คุณจะได้เรียนรู้วิธีอัปโหลดข้อมูลดิบจากบัญชี Google Ads ไปยัง BigQuery และระบุแท็ก UTM ทั้งหมดสำหรับแคมเปญที่ติดป้ายกำกับอัตโนมัติ
คุณต้องใช้ OWOX BI เพื่อเชื่อมโยงข้อมูลแคมเปญกับกิจกรรมของผู้ใช้บนไซต์ ลงชื่อสมัครใช้สำหรับการสาธิต แล้วเราจะให้รายละเอียดเกี่ยวกับความท้าทายทั้งหมดที่คุณสามารถแก้ไขได้ด้วย OWOX BI
สารบัญ
- ทำไมคุณถึงต้องการข้อมูลดิบจาก Google Ads
- สองวิธีในการอัปโหลดข้อมูลดิบจาก Google Ads ไปยัง BigQuery
- วิธีกำหนดค่าการอัปโหลดโดยใช้ Data Transfer
- วิธีตั้งค่าการอัปโหลดโดยใช้ Ads Script
- วิธีเชื่อมต่อการดาวน์โหลดข้อมูลจาก Google Ads กับ OWOX BI
- เคล็ดลับที่เป็นประโยชน์
ค้นหามูลค่าที่แท้จริงของแคมเปญ
นำเข้าข้อมูลค่าใช้จ่ายไปยัง Google Analytics โดยอัตโนมัติจากบริการโฆษณาทั้งหมดของคุณ เปรียบเทียบต้นทุนแคมเปญ CPC และ ROAS ในรายงานเดียว

ทำไมคุณถึงต้องการข้อมูลดิบจาก Google Ads
ข้อมูลดิบจาก Google Ads จะช่วยให้คุณวิเคราะห์แคมเปญโฆษณาได้อย่างแม่นยำถึงแต่ละคีย์เวิร์ด การอัปโหลดข้อมูลไปยัง BigQuery คุณสามารถ:
- สร้างรายงานตามรายละเอียดที่คุณต้องการโดยไม่มีข้อจำกัดของ GA
- กำหนดประสิทธิภาพของแคมเปญโฆษณาที่ระดับเซสชันและผู้ใช้
- คำนวณ ROI, ROAS, CRR ตามภูมิภาค ประเภทผู้ใช้ (ใหม่หรือที่ส่งคืน) อุปกรณ์ และพารามิเตอร์อื่นๆ
- จัดการอัตราของคุณอย่างมีประสิทธิภาพและสร้างรายการรีมาร์เก็ตติ้ง
- รวมข้อมูลจาก Google Ads, Google Analytics และ CRM เพื่อประเมินประสิทธิภาพของแคมเปญตามส่วนต่างและความสามารถในการแลกของรางวัล
- ฝึกโมเดล ML ของคุณเพื่อการวางแผนที่แม่นยำยิ่งขึ้น
เพื่อให้เข้าใจว่าแคมเปญ โฆษณา และคีย์เวิร์ดใดนำผู้ใช้มาที่ไซต์ของคุณ คุณต้องรวมข้อมูลจาก Google Ads และ Analytics เข้าใน BigQuery คุณสามารถทำได้โดยใช้การสตรีม OWOX BI
การสตรีมข้อมูลนี้จะส่งข้อมูลพฤติกรรมผู้ใช้ที่ไม่ได้สุ่มตัวอย่างบนไซต์ของคุณไปยัง GBQ Hit จะถูกส่งในเวลาจริง จากนั้นเซสชันจะถูกสร้างขึ้นตาม Hit เหล่านี้
ข้อมูลแหล่งที่มาของการรับส่งข้อมูล OWOX BI นำมาจากมาร์กอัปโฆษณาแท็ก UTM แท็กเป็นแบบแมนนวลและอัตโนมัติ
สมมติว่าคุณทำเครื่องหมายโฆษณาด้วยตนเองและได้ URL นี้:
https://example.com/?utm_source=facebook&utm_medium=cpc&utm_campaign=utm_tags
ในกรณีนี้ หลังจากที่คุณเชื่อมต่อ OWOX BI แล้ว คุณจะมีข้อมูลแหล่งที่มา ช่องทาง และแคมเปญในตาราง GBQ:
- TrafficSource.source — google
- TrafficSource.medium — cpc
- TrafficSource.campaign — utm_tags
อ่านเพิ่มเติมเกี่ยวกับวิธีการสร้างแท็ก UTM อย่างถูกต้อง
หากคุณเปิดใช้งานมาร์กอัปอัตโนมัติในบริการโฆษณา จะมีการกำหนดพารามิเตอร์ gclid พิเศษให้กับโฆษณาแต่ละรายการของคุณ มันถูกเพิ่มไปยัง URL ของหน้า Landing Page เมื่อผู้ใช้คลิกที่ประกาศ
ตัวอย่างของลิงค์ดังกล่าว:
http://www.example.com/?gclid=TeSter-123
หากคุณใช้มาร์กอัปอัตโนมัติ คุณจะรับแหล่งที่มา สื่อ หรือแคมเปญจาก gclid ไม่ได้หากไม่มีข้อมูลดิบ ช่องเหล่านี้จะว่างเปล่าในตาราง BigQuery ที่ OWOX BI รวบรวม
คุณทำอะไรได้บ้างในกรณีเช่นนี้ และคุณจะได้ชื่อแคมเปญและพารามิเตอร์อื่นๆ โดยมีเพียง gclid ได้อย่างไร กำหนดค่าการอัปโหลดอัตโนมัติจาก Google Ads เป็น GBQ
หมายเหตุ: หากไม่ได้ทำเครื่องหมายประกาศเลย OWOX BI จะกำหนดลิงก์ดังนี้:
- สำหรับแหล่งที่มาที่ไม่ใช่ของ Google เป็นการเข้าชมจากการอ้างอิง (เช่น facebook/referral)
- สำหรับแหล่งที่มาของ Google เป็นการเข้าชมโดยตรง (โดยตรง/ไม่มี)
หากมีการเข้าชมโดยตรง/ไม่มีเลยในรายงานของคุณ คุณอาจไม่ได้เปิดใช้งานการกรองบอท หรือคุณอาจมีโฆษณาที่ไม่ได้ติดแท็กจำนวนมาก
สองวิธีในการอัปโหลดข้อมูลดิบจาก Google Ads ไปยัง BigQuery
เราใช้และแนะนำ 2 วิธีในการอัปโหลดข้อมูลดิบจาก Google Ads: Data Transfer Connector และ Ads Script
วิธีที่คุณเลือกขึ้นอยู่กับเป้าหมายและงบประมาณของคุณ
คุณสมบัติการถ่ายโอนข้อมูล
- การผสานรวมกับ GBQ
- ดาวน์โหลดข้อมูลย้อนหลังในช่วงเวลาใดก็ได้โดยไม่มีข้อจำกัด
- ไม่คิดเงิน.
คุณลักษณะสคริปต์โฆษณาของ Google
- ฟรี.
- คุณไม่สามารถอัปโหลดข้อมูลย้อนหลังได้ ดาวน์โหลดเฉพาะข้อมูลของวันก่อนหน้า
- ต้องการมากกว่านี้หากคุณต้องการตั้งค่าการอัปโหลดจากบัญชีจำนวนมาก คุณจะต้องทำการเปลี่ยนแปลงสคริปต์ด้วยตนเองสำหรับแต่ละบัญชี ในขณะเดียวกันก็มีความเสี่ยงสูงที่จะทำผิดพลาด
สิ่งที่คุณต้องการสำหรับการตั้งค่า
โครงการและบัญชีที่ใช้งานอยู่ใน:
- Google คลาวด์แพลตฟอร์ม (GCP)
- Google BigQuery (GBQ)
- OWOX BI
- Google Ads
เข้าถึง:
- เจ้าของใน GCP
- ผู้ดูแลระบบใน GBQ
- การแก้ไขใน OWOX BI สำคัญ: เฉพาะผู้ใช้ที่สร้าง Google Analytics → ไปป์ไลน์การสตรีม Google BigQuery เท่านั้นที่สามารถเปิดการดาวน์โหลดจาก Google Ads
- การอ่านใน Google Ads
วิธีให้สิทธิ์การเข้าถึงใน GBQ
เปิดคอนโซล GCP แล้วเลือก IAM และผู้ดูแลระบบ — จัดการทรัพยากรจากเมนูด้านข้าง จากนั้นเลือกโครงการและคลิกเพิ่มสมาชิก ป้อนอีเมลของผู้ใช้ เลือกบทบาทผู้ดูแลระบบ BigQuery และบันทึกการเปลี่ยนแปลงของคุณ

วิธีกำหนดค่าการอัปโหลดโดยใช้ Data Transfer
ขั้นตอนที่ 1 สร้างโครงการใน Google Cloud Platform
หากคุณมีโปรเจ็กต์ใน GCP อยู่แล้ว ให้ข้ามขั้นตอนนี้ หากไม่เป็นเช่นนั้น ให้เปิดคอนโซล GCP แล้วเลือก IAM และผู้ดูแลระบบ — จัดการทรัพยากรจากเมนูด้านข้าง คลิกปุ่มสร้างโครงการ จากนั้นป้อนชื่อโครงการ ระบุองค์กร แล้วคลิกสร้าง:

อย่าลืมเปิดใช้งานการเรียกเก็บเงิน ในการดำเนินการนี้ ให้เปิดแท็บ การเรียกเก็บเงิน — การจัดการบัญชี ในเมนูด้านข้าง เลือกโครงการ และเชื่อมโยงบัญชีสำหรับการเรียกเก็บเงิน:

ถัดไป กรอกข้อมูลในฟิลด์ทั้งหมดโดยป้อนรายชื่อติดต่อและรายละเอียดบัตรชำระเงินของคุณ หากนี่เป็นโครงการแรกของคุณใน GCP คุณจะได้รับ $300 ซึ่งสามารถใช้ได้เป็นเวลา 12 เดือน โครงการที่มีบัญชี Google Ads 1-2 บัญชีและผู้ใช้ที่ไม่ซ้ำสูงสุด 100,000 คนต่อเดือนจะเพียงพอสำหรับหนึ่งปี เมื่อคุณใช้วงเงินนี้จนหมด คุณไม่จำเป็นต้องคืนเงิน สำหรับการใช้งานต่อไป คุณเพียงแค่เติมเงินในบัตรที่คุณเชื่อมโยงกับโครงการ
ขั้นตอนที่ 2 เปิด API BigQuery
หลังจากที่คุณสร้างโปรเจ็กต์ คุณต้องเปิดใช้งาน BigQuery API โดยไปที่ APIs & Services — Dashboard จากเมนูด้านข้าง GCP เลือกโปรเจ็กต์ แล้วคลิก Enable APIs and Services:

ในไลบรารี API ค้นหา "BigQuery API" แล้วคลิกเปิดใช้งาน:

หากต้องการใช้ API ให้คลิกสร้างข้อมูลรับรอง:

จากรายการดรอปดาวน์ ให้เลือก BigQuery API แล้วคลิก ฉันต้องการข้อมูลประจำตัวใด

สร้างชื่อบัญชีบริการและระบุระดับการเข้าถึงบทบาท BigQuery เลือกประเภทของคีย์ JSON แล้วคลิกดำเนินการต่อ:

ขั้นตอนที่ 3 เปิดใช้งาน Data Transfer API
ถัดไป คุณต้องเปิดใช้งานบริการข้อมูลใน BigQuery ในการดำเนินการนี้ ให้เปิด GBQ และเลือก Transfers จากเมนูด้านข้างทางด้านซ้าย จากนั้นเปิดใช้ BigQuery Data Transfer API:

ขั้นตอนที่ 4 เตรียมชุดข้อมูลใน GBQ
ใน BigQuery เลือกโครงการแล้วคลิกปุ่มสร้างชุดข้อมูลทางด้านขวา กรอกข้อมูลในฟิลด์ที่จำเป็นทั้งหมดสำหรับชุดข้อมูลใหม่ (ชื่อ ตำแหน่ง การเก็บรักษา):

ขั้นตอนที่ 5. ตั้งค่าการถ่ายโอนข้อมูลจาก Google Ads
คลิกแท็บ Transfers ที่เมนูด้านข้าง จากนั้นคลิก Create Transfer จากนั้นเลือกแหล่งที่มาของ Google Ads (เดิมคือ AdWords) แล้วป้อนชื่อการอัปโหลด เช่น การโอนข้อมูล
ภายใต้ ตัวเลือกกำหนดการ คุณสามารถปล่อยให้การตั้งค่าเริ่มต้นเป็น เริ่มเลย หรือตั้งค่าวันที่และเวลาที่คุณต้องการเริ่มดาวน์โหลด ในฟิลด์ทำซ้ำ เลือกความถี่ในการอัปโหลด: รายวัน รายสัปดาห์ รายเดือนตามต้องการ ฯลฯ

จากนั้น คุณต้องระบุชุดข้อมูล GBQ เพื่อโหลดรายงานจาก Google Ads เข้าไป ป้อนรหัสลูกค้า (นี่คือรหัสของบัญชี Google Ads หรือรหัส MCC) แล้วคลิกเพิ่ม คุณดูรหัสลูกค้าได้ในบัญชี Google Ads ที่มุมขวาบนข้างอีเมล

จากนั้นคุณต้องอนุญาตบัญชี Gmail ที่คุณใช้ ในวันถัดไป ข้อมูลจะปรากฏในชุดข้อมูลที่คุณระบุเมื่อคุณตั้งค่าการโอน
ด้วยเหตุนี้ คุณจะได้รับข้อมูลดิบจำนวนมากใน GBQ ที่คุณสามารถใช้ได้: ตารางตามแคมเปญ ผู้ชม ตารางทั่วไป (กำหนดเอง) คำหลัก และ Conversion ตัวอย่างเช่น หากคุณต้องการสร้างแดชบอร์ดแบบกำหนดเอง คุณสามารถดึงข้อมูลที่ไม่ได้รวมจากตารางเหล่านี้
วิธีตั้งค่าการอัปโหลดโดยใช้ Ads Script
เปิดบัญชี Google Ads ของคุณ คลิกเครื่องมือและการตั้งค่าที่มุมขวาบน เลือกการดำเนินการเป็นกลุ่ม — สคริปต์ แล้วคลิกสัญลักษณ์บวก:

จากนั้น ที่มุมบนขวา ให้คลิกปุ่ม API ขั้นสูง เลือก BigQuery แล้วบันทึกการเปลี่ยนแปลงของคุณ:

อย่าลืมลงชื่อสมัครใช้ด้วยบัญชีที่คุณลงชื่อเข้าใช้ Google Ads ด้วย:

คัดลอกสคริปต์ด้านล่าง ใน BIGQUERY_PROJECT_ID, BIGQUERY_DATASET_ID และบรรทัดอีเมลของคุณ ให้แทนที่ค่าด้วยข้อมูลของคุณเอง ได้แก่ ชื่อโปรเจ็กต์ ชุดข้อมูล GBQ และอีเมล วางข้อความสคริปต์ลงในโปรแกรมแก้ไขข้อความ
/** * @name Export Data to BigQuery * * @overview The Export Data to BigQuery script sets up a BigQuery * dataset and tables, downloads a report from AdWords and then * loads the report to BigQuery. * * @author AdWords Scripts Team [[email protected]] * * @version 1.3 */ var CONFIG = { BIGQUERY_PROJECT_ID: 'BQ project name', BIGQUERY_DATASET_ID: AdWordsApp.currentAccount().getCustomerId().replace(/-/g, '_'), // Truncate existing data, otherwise will append. TRUNCATE_EXISTING_DATASET: false, TRUNCATE_EXISTING_TABLES: true, // Lists of reports and fields to retrieve from AdWords. REPORTS: [], RECIPIENT_EMAILS: [ 'Your email' ] }; var report = { NAME: 'CLICK_PERFORMANCE_REPORT', //https://developers.google.com/adwords/api/docs/appendix/reports/click-performance-report CONDITIONS: '', FIELDS: {'AccountDescriptiveName': 'STRING', 'AdFormat': 'STRING', 'AdGroupId': 'STRING', 'AdGroupName': 'STRING', 'AoiCountryCriteriaId': 'STRING', 'CampaignId': 'STRING', 'CampaignLocationTargetId': 'STRING', 'CampaignName': 'STRING', 'CampaignStatus': 'STRING', 'Clicks': 'INTEGER', 'ClickType': 'STRING', 'CreativeId': 'STRING', 'CriteriaId': 'STRING', 'CriteriaParameters': 'STRING', 'Date': 'DATE', 'Device': 'STRING', 'ExternalCustomerId': 'STRING', 'GclId': 'STRING', 'KeywordMatchType': 'STRING', 'LopCountryCriteriaId': 'STRING', 'Page': 'INTEGER' }, DATE_RANGE: new Date(new Date().setDate(new Date().getDate()-1)).toISOString().slice(0, 10).replace(/-/g, "")+','+new Date(new Date().setDate(new Date().getDate()-1)).toISOString().slice(0, 10).replace(/-/g, ""), DATE: new Date(new Date().setDate(new Date().getDate()-1)).toISOString().slice(0, 10).replace(/-/g, "") }; //Regular export CONFIG.REPORTS.push(JSON.parse(JSON.stringify(report))); //One-time historical export //for(var i=2;i<91;i++){ // report.DATE_RANGE = new Date(new Date().setDate(new Date().getDate()-i)).toISOString().slice(0, 10).replace(/-/g, "")+','+new Date(new Date().setDate(new Date().getDate()-i)).toISOString().slice(0, 10).replace(/-/g, ""); // report.DATE = new Date(new Date().setDate(new Date().getDate()-i)).toISOString().slice(0, 10).replace(/-/g, ""); // CONFIG.REPORTS.push(JSON.parse(JSON.stringify(report))); //} /** * Main method */ function main() { createDataset(); for (var i = 0; i < CONFIG.REPORTS.length; i++) { var reportConfig = CONFIG.REPORTS[i]; createTable(reportConfig); } var jobIds = processReports(); waitTillJobsComplete(jobIds); sendEmail(jobIds); } /** * Creates a new dataset. * * If a dataset with the same id already exists and the truncate flag * is set, will truncate the old dataset. If the truncate flag is not * set, then will not create a new dataset. */ function createDataset() { if (datasetExists()) { if (CONFIG.TRUNCATE_EXISTING_DATASET) { BigQuery.Datasets.remove(CONFIG.BIGQUERY_PROJECT_ID, CONFIG.BIGQUERY_DATASET_ID, {'deleteContents' : true}); Logger.log('Truncated dataset.'); } else { Logger.log('Dataset %s already exists. Will not recreate.', CONFIG.BIGQUERY_DATASET_ID); return; } } // Create new dataset. var dataSet = BigQuery.newDataset(); dataSet.friendlyName = CONFIG.BIGQUERY_DATASET_ID; dataSet.datasetReference = BigQuery.newDatasetReference(); dataSet.datasetReference.projectId = CONFIG.BIGQUERY_PROJECT_ID; dataSet.datasetReference.datasetId = CONFIG.BIGQUERY_DATASET_ID; dataSet = BigQuery.Datasets.insert(dataSet, CONFIG.BIGQUERY_PROJECT_ID); Logger.log('Created dataset with id %s.', dataSet.id); } /** * Checks if dataset already exists in project. * * @return {boolean} Returns true if dataset already exists. */ function datasetExists() { // Get a list of all datasets in project. var datasets = BigQuery.Datasets.list(CONFIG.BIGQUERY_PROJECT_ID); var datasetExists = false; // Iterate through each dataset and check for an id match. if (datasets.datasets != null) { for (var i = 0; i < datasets.datasets.length; i++) { var dataset = datasets.datasets[i]; if (dataset.datasetReference.datasetId == CONFIG.BIGQUERY_DATASET_ID) { datasetExists = true; break; } } } return datasetExists; } /** * Creates a new table. * * If a table with the same id already exists and the truncate flag * is set, will truncate the old table. If the truncate flag is not * set, then will not create a new table. * * @param {Object} reportConfig Report configuration including report name, * conditions, and fields. */ function createTable(reportConfig) { var tableName = reportConfig.NAME+reportConfig.DATE; if (tableExists(tableName)) { if (CONFIG.TRUNCATE_EXISTING_TABLES) { BigQuery.Tables.remove(CONFIG.BIGQUERY_PROJECT_ID, CONFIG.BIGQUERY_DATASET_ID, tableName); Logger.log('Truncated table %s.', tableName); } else { Logger.log('Table %s already exists. Will not recreate.', tableName); return; } } // Create new table. var table = BigQuery.newTable(); var schema = BigQuery.newTableSchema(); var bigQueryFields = []; // Add each field to table schema. var fieldNames = Object.keys(reportConfig.FIELDS); for (var i = 0; i < fieldNames.length; i++) { var fieldName = fieldNames[i]; var bigQueryFieldSchema = BigQuery.newTableFieldSchema(); bigQueryFieldSchema.description = fieldName; bigQueryFieldSchema.name = fieldName; bigQueryFieldSchema.type = reportConfig.FIELDS[fieldName]; bigQueryFields.push(bigQueryFieldSchema); } schema.fields = bigQueryFields; table.schema = schema; table.friendlyName = tableName; table.tableReference = BigQuery.newTableReference(); table.tableReference.datasetId = CONFIG.BIGQUERY_DATASET_ID; table.tableReference.projectId = CONFIG.BIGQUERY_PROJECT_ID; table.tableReference.tableId = tableName; table = BigQuery.Tables.insert(table, CONFIG.BIGQUERY_PROJECT_ID, CONFIG.BIGQUERY_DATASET_ID); Logger.log('Created table with id %s.', table.id); } /** * Checks if table already exists in dataset. * * @param {string} tableId The table id to check existence. * * @return {boolean} Returns true if table already exists. */ function tableExists(tableId) { // Get a list of all tables in the dataset. var tables = BigQuery.Tables.list(CONFIG.BIGQUERY_PROJECT_ID, CONFIG.BIGQUERY_DATASET_ID); var tableExists = false; // Iterate through each table and check for an id match. if (tables.tables != null) { for (var i = 0; i < tables.tables.length; i++) { var table = tables.tables[i]; if (table.tableReference.tableId == tableId) { tableExists = true; break; } } } return tableExists; } /** * Process all configured reports * * Iterates through each report to: retrieve AdWords data, * backup data to Drive (if configured), load data to BigQuery. * * @return {Array.<string>} jobIds The list of all job ids. */ function processReports() { var jobIds = []; // Iterate over each report type. for (var i = 0; i < CONFIG.REPORTS.length; i++) { var reportConfig = CONFIG.REPORTS[i]; Logger.log('Running report %s', reportConfig.NAME); // Get data as csv var csvData = retrieveAdwordsReport(reportConfig); //Logger.log(csvData); // Convert to Blob format. var blobData = Utilities.newBlob(csvData, 'application/octet-stream'); // Load data var jobId = loadDataToBigquery(reportConfig, blobData); jobIds.push(jobId); } return jobIds; } /** * Retrieves AdWords data as csv and formats any fields * to BigQuery expected format. * * @param {Object} reportConfig Report configuration including report name, * conditions, and fields. * * @return {string} csvData Report in csv format. */ function retrieveAdwordsReport(reportConfig) { var fieldNames = Object.keys(reportConfig.FIELDS); var query = 'SELECT ' + fieldNames.join(', ') + ' FROM ' + reportConfig.NAME + '' + reportConfig.CONDITIONS + ' DURING ' + reportConfig.DATE_RANGE; Logger.log(query); var report = AdWordsApp.report(query); var rows = report.rows(); var csvRows = []; // Header row csvRows.push(fieldNames.join(',')); // Iterate over each row. while (rows.hasNext()) { var row = rows.next(); var csvRow = []; for (var i = 0; i < fieldNames.length; i++) { var fieldName = fieldNames[i]; var fieldValue = row[fieldName].toString(); var fieldType = reportConfig.FIELDS[fieldName]; // Strip off % and perform any other formatting here. if (fieldType == 'FLOAT' || fieldType == 'INTEGER') { if (fieldValue.charAt(fieldValue.length - 1) == '%') { fieldValue = fieldValue.substring(0, fieldValue.length - 1); } fieldValue = fieldValue.replace(/,/g,''); if (fieldValue == '--' || fieldValue == 'Unspecified') { fieldValue = '' } } // Add double quotes to any string values. if (fieldType == 'STRING') { if (fieldValue == '--') { fieldValue = '' } fieldValue = fieldValue.replace(/"/g, '""'); fieldValue = '"' + fieldValue + '"' } csvRow.push(fieldValue); } csvRows.push(csvRow.join(',')); } Logger.log('Downloaded ' + reportConfig.NAME + ' with ' + csvRows.length + ' rows.'); return csvRows.join('\n'); } /** * Creates a BigQuery insertJob to load csv data. * * @param {Object} reportConfig Report configuration including report name, * conditions, and fields. * @param {Blob} data Csv report data as an 'application/octet-stream' blob. * * @return {string} jobId The job id for upload. */ function loadDataToBigquery(reportConfig, data) { // Create the data upload job. var job = { configuration: { load: { destinationTable: { projectId: CONFIG.BIGQUERY_PROJECT_ID, datasetId: CONFIG.BIGQUERY_DATASET_ID, tableId: reportConfig.NAME + reportConfig.DATE }, skipLeadingRows: 1 } } }; var insertJob = BigQuery.Jobs.insert(job, CONFIG.BIGQUERY_PROJECT_ID, data); Logger.log('Load job started for %s. Check on the status of it here: ' + 'https://bigquery.cloud.google.com/jobs/%s', reportConfig.NAME, CONFIG.BIGQUERY_PROJECT_ID); return insertJob.jobReference.jobId; } /** * Polls until all jobs are 'DONE'. * * @param {Array.<string>} jobIds The list of all job ids. */ function waitTillJobsComplete(jobIds) { var complete = false; var remainingJobs = jobIds; while (!complete) { if (AdWordsApp.getExecutionInfo().getRemainingTime() < 5){ Logger.log('Script is about to timeout, jobs ' + remainingJobs.join(',') + ' are still incomplete.'); } remainingJobs = getIncompleteJobs(remainingJobs); if (remainingJobs.length == 0) { complete = true; } if (!complete) { Logger.log(remainingJobs.length + ' jobs still being processed.'); // Wait 5 seconds before checking status again. Utilities.sleep(5000); } } Logger.log('All jobs processed.'); } /** * Iterates through jobs and returns the ids for those jobs * that are not 'DONE'. * * @param {Array.<string>} jobIds The list of job ids. * * @return {Array.<string>} remainingJobIds The list of remaining job ids. */ function getIncompleteJobs(jobIds) { var remainingJobIds = []; for (var i = 0; i < jobIds.length; i++) { var jobId = jobIds[i]; var getJob = BigQuery.Jobs.get(CONFIG.BIGQUERY_PROJECT_ID, jobId); if (getJob.status.state != 'DONE') { remainingJobIds.push(jobId); } } return remainingJobIds; } /** * Sends a notification email that jobs have completed loading. * * @param {Array.<string>} jobIds The list of all job ids. */ function sendEmail(jobIds) { var html = []; html.push( '<html>', '<body>', '<table width=800 cellpadding=0 border=0 cellspacing=0>', '<tr>', '<td colspan=2 align=right>', "<div style='font: italic normal 10pt Times New Roman, serif; " + "margin: 0; color: #666; padding-right: 5px;'>" + 'Powered by AdWords Scripts</div>', '</td>', '</tr>', "<tr bgcolor='#3c78d8'>", '<td width=500>', "<div style='font: normal 18pt verdana, sans-serif; " + "padding: 3px 10px; color: white'>Adwords data load to " + "Bigquery report</div>", '</td>', '<td align=right>', "<div style='font: normal 18pt verdana, sans-serif; " + "padding: 3px 10px; color: white'>", AdWordsApp.currentAccount().getCustomerId(), '</tr>', '</table>', '<table width=800 cellpadding=0 border=1 cellspacing=0>', "<tr bgcolor='#ddd'>", "<td style='font: 12pt verdana, sans-serif; " + 'padding: 5px 0px 5px 5px; background-color: #ddd; ' + "text-align: left'>Report</td>", "<td style='font: 12pt verdana, sans-serif; " + 'padding: 5px 0px 5px 5px; background-color: #ddd; ' + "text-align: left'>JobId</td>", "<td style='font: 12pt verdana, sans-serif; " + 'padding: 5px 0px 5x 5px; background-color: #ddd; ' + "text-align: left'>Rows</td>", "<td style='font: 12pt verdana, sans-serif; " + 'padding: 5px 0px 5x 5px; background-color: #ddd; ' + "text-align: left'>State</td>", "<td style='font: 12pt verdana, sans-serif; " + 'padding: 5px 0px 5x 5px; background-color: #ddd; ' + "text-align: left'>ErrorResult</td>", '</tr>', createTableRows(jobIds), '</table>', '</body>', '</html>'); MailApp.sendEmail(CONFIG.RECIPIENT_EMAILS.join(','), 'Adwords data load to Bigquery Complete', '', {htmlBody: html.join('\n')}); } /** * Creates table rows for email report. * * @param {Array.<string>} jobIds The list of all job ids. */ function createTableRows(jobIds) { var html = []; for (var i = 0; i < jobIds.length; i++) { var jobId = jobIds[i]; var job = BigQuery.Jobs.get(CONFIG.BIGQUERY_PROJECT_ID, jobId); var errorResult = '' if (job.status.errorResult) { errorResult = job.status.errorResult; } html.push('<tr>', "<td style='padding: 0px 10px'>" + job.configuration.load.destinationTable.tableId + '</td>', "<td style='padding: 0px 10px'>" + jobId + '</td>', "<td style='padding: 0px 10px'>" + job.statistics.load?job.statistics.load.outputRows:0 + '</td>', "<td style='padding: 0px 10px'>" + job.status.state + '</td>', "<td style='padding: 0px 10px'>" + errorResult + '</td>', '</tr>'); } return html.join('\n'); }
/** * @name Export Data to BigQuery * * @overview The Export Data to BigQuery script sets up a BigQuery * dataset and tables, downloads a report from AdWords and then * loads the report to BigQuery. * * @author AdWords Scripts Team [[email protected]] * * @version 1.3 */ var CONFIG = { BIGQUERY_PROJECT_ID: 'BQ project name', BIGQUERY_DATASET_ID: AdWordsApp.currentAccount().getCustomerId().replace(/-/g, '_'), // Truncate existing data, otherwise will append. TRUNCATE_EXISTING_DATASET: false, TRUNCATE_EXISTING_TABLES: true, // Lists of reports and fields to retrieve from AdWords. REPORTS: [], RECIPIENT_EMAILS: [ 'Your email' ] }; var report = { NAME: 'CLICK_PERFORMANCE_REPORT', //https://developers.google.com/adwords/api/docs/appendix/reports/click-performance-report CONDITIONS: '', FIELDS: {'AccountDescriptiveName': 'STRING', 'AdFormat': 'STRING', 'AdGroupId': 'STRING', 'AdGroupName': 'STRING', 'AoiCountryCriteriaId': 'STRING', 'CampaignId': 'STRING', 'CampaignLocationTargetId': 'STRING', 'CampaignName': 'STRING', 'CampaignStatus': 'STRING', 'Clicks': 'INTEGER', 'ClickType': 'STRING', 'CreativeId': 'STRING', 'CriteriaId': 'STRING', 'CriteriaParameters': 'STRING', 'Date': 'DATE', 'Device': 'STRING', 'ExternalCustomerId': 'STRING', 'GclId': 'STRING', 'KeywordMatchType': 'STRING', 'LopCountryCriteriaId': 'STRING', 'Page': 'INTEGER' }, DATE_RANGE: new Date(new Date().setDate(new Date().getDate()-1)).toISOString().slice(0, 10).replace(/-/g, "")+','+new Date(new Date().setDate(new Date().getDate()-1)).toISOString().slice(0, 10).replace(/-/g, ""), DATE: new Date(new Date().setDate(new Date().getDate()-1)).toISOString().slice(0, 10).replace(/-/g, "") }; //Regular export CONFIG.REPORTS.push(JSON.parse(JSON.stringify(report))); //One-time historical export //for(var i=2;i<91;i++){ // report.DATE_RANGE = new Date(new Date().setDate(new Date().getDate()-i)).toISOString().slice(0, 10).replace(/-/g, "")+','+new Date(new Date().setDate(new Date().getDate()-i)).toISOString().slice(0, 10).replace(/-/g, ""); // report.DATE = new Date(new Date().setDate(new Date().getDate()-i)).toISOString().slice(0, 10).replace(/-/g, ""); // CONFIG.REPORTS.push(JSON.parse(JSON.stringify(report))); //} /** * Main method */ function main() { createDataset(); for (var i = 0; i < CONFIG.REPORTS.length; i++) { var reportConfig = CONFIG.REPORTS[i]; createTable(reportConfig); } var jobIds = processReports(); waitTillJobsComplete(jobIds); sendEmail(jobIds); } /** * Creates a new dataset. * * If a dataset with the same id already exists and the truncate flag * is set, will truncate the old dataset. If the truncate flag is not * set, then will not create a new dataset. */ function createDataset() { if (datasetExists()) { if (CONFIG.TRUNCATE_EXISTING_DATASET) { BigQuery.Datasets.remove(CONFIG.BIGQUERY_PROJECT_ID, CONFIG.BIGQUERY_DATASET_ID, {'deleteContents' : true}); Logger.log('Truncated dataset.'); } else { Logger.log('Dataset %s already exists. Will not recreate.', CONFIG.BIGQUERY_DATASET_ID); return; } } // Create new dataset. var dataSet = BigQuery.newDataset(); dataSet.friendlyName = CONFIG.BIGQUERY_DATASET_ID; dataSet.datasetReference = BigQuery.newDatasetReference(); dataSet.datasetReference.projectId = CONFIG.BIGQUERY_PROJECT_ID; dataSet.datasetReference.datasetId = CONFIG.BIGQUERY_DATASET_ID; dataSet = BigQuery.Datasets.insert(dataSet, CONFIG.BIGQUERY_PROJECT_ID); Logger.log('Created dataset with id %s.', dataSet.id); } /** * Checks if dataset already exists in project. * * @return {boolean} Returns true if dataset already exists. */ function datasetExists() { // Get a list of all datasets in project. var datasets = BigQuery.Datasets.list(CONFIG.BIGQUERY_PROJECT_ID); var datasetExists = false; // Iterate through each dataset and check for an id match. if (datasets.datasets != null) { for (var i = 0; i < datasets.datasets.length; i++) { var dataset = datasets.datasets[i]; if (dataset.datasetReference.datasetId == CONFIG.BIGQUERY_DATASET_ID) { datasetExists = true; break; } } } return datasetExists; } /** * Creates a new table. * * If a table with the same id already exists and the truncate flag * is set, will truncate the old table. If the truncate flag is not * set, then will not create a new table. * * @param {Object} reportConfig Report configuration including report name, * conditions, and fields. */ function createTable(reportConfig) { var tableName = reportConfig.NAME+reportConfig.DATE; if (tableExists(tableName)) { if (CONFIG.TRUNCATE_EXISTING_TABLES) { BigQuery.Tables.remove(CONFIG.BIGQUERY_PROJECT_ID, CONFIG.BIGQUERY_DATASET_ID, tableName); Logger.log('Truncated table %s.', tableName); } else { Logger.log('Table %s already exists. Will not recreate.', tableName); return; } } // Create new table. var table = BigQuery.newTable(); var schema = BigQuery.newTableSchema(); var bigQueryFields = []; // Add each field to table schema. var fieldNames = Object.keys(reportConfig.FIELDS); for (var i = 0; i < fieldNames.length; i++) { var fieldName = fieldNames[i]; var bigQueryFieldSchema = BigQuery.newTableFieldSchema(); bigQueryFieldSchema.description = fieldName; bigQueryFieldSchema.name = fieldName; bigQueryFieldSchema.type = reportConfig.FIELDS[fieldName]; bigQueryFields.push(bigQueryFieldSchema); } schema.fields = bigQueryFields; table.schema = schema; table.friendlyName = tableName; table.tableReference = BigQuery.newTableReference(); table.tableReference.datasetId = CONFIG.BIGQUERY_DATASET_ID; table.tableReference.projectId = CONFIG.BIGQUERY_PROJECT_ID; table.tableReference.tableId = tableName; table = BigQuery.Tables.insert(table, CONFIG.BIGQUERY_PROJECT_ID, CONFIG.BIGQUERY_DATASET_ID); Logger.log('Created table with id %s.', table.id); } /** * Checks if table already exists in dataset. * * @param {string} tableId The table id to check existence. * * @return {boolean} Returns true if table already exists. */ function tableExists(tableId) { // Get a list of all tables in the dataset. var tables = BigQuery.Tables.list(CONFIG.BIGQUERY_PROJECT_ID, CONFIG.BIGQUERY_DATASET_ID); var tableExists = false; // Iterate through each table and check for an id match. if (tables.tables != null) { for (var i = 0; i < tables.tables.length; i++) { var table = tables.tables[i]; if (table.tableReference.tableId == tableId) { tableExists = true; break; } } } return tableExists; } /** * Process all configured reports * * Iterates through each report to: retrieve AdWords data, * backup data to Drive (if configured), load data to BigQuery. * * @return {Array.<string>} jobIds The list of all job ids. */ function processReports() { var jobIds = []; // Iterate over each report type. for (var i = 0; i < CONFIG.REPORTS.length; i++) { var reportConfig = CONFIG.REPORTS[i]; Logger.log('Running report %s', reportConfig.NAME); // Get data as csv var csvData = retrieveAdwordsReport(reportConfig); //Logger.log(csvData); // Convert to Blob format. var blobData = Utilities.newBlob(csvData, 'application/octet-stream'); // Load data var jobId = loadDataToBigquery(reportConfig, blobData); jobIds.push(jobId); } return jobIds; } /** * Retrieves AdWords data as csv and formats any fields * to BigQuery expected format. * * @param {Object} reportConfig Report configuration including report name, * conditions, and fields. * * @return {string} csvData Report in csv format. */ function retrieveAdwordsReport(reportConfig) { var fieldNames = Object.keys(reportConfig.FIELDS); var query = 'SELECT ' + fieldNames.join(', ') + ' FROM ' + reportConfig.NAME + '' + reportConfig.CONDITIONS + ' DURING ' + reportConfig.DATE_RANGE; Logger.log(query); var report = AdWordsApp.report(query); var rows = report.rows(); var csvRows = []; // Header row csvRows.push(fieldNames.join(',')); // Iterate over each row. while (rows.hasNext()) { var row = rows.next(); var csvRow = []; for (var i = 0; i < fieldNames.length; i++) { var fieldName = fieldNames[i]; var fieldValue = row[fieldName].toString(); var fieldType = reportConfig.FIELDS[fieldName]; // Strip off % and perform any other formatting here. if (fieldType == 'FLOAT' || fieldType == 'INTEGER') { if (fieldValue.charAt(fieldValue.length - 1) == '%') { fieldValue = fieldValue.substring(0, fieldValue.length - 1); } fieldValue = fieldValue.replace(/,/g,''); if (fieldValue == '--' || fieldValue == 'Unspecified') { fieldValue = '' } } // Add double quotes to any string values. if (fieldType == 'STRING') { if (fieldValue == '--') { fieldValue = '' } fieldValue = fieldValue.replace(/"/g, '""'); fieldValue = '"' + fieldValue + '"' } csvRow.push(fieldValue); } csvRows.push(csvRow.join(',')); } Logger.log('Downloaded ' + reportConfig.NAME + ' with ' + csvRows.length + ' rows.'); return csvRows.join('\n'); } /** * Creates a BigQuery insertJob to load csv data. * * @param {Object} reportConfig Report configuration including report name, * conditions, and fields. * @param {Blob} data Csv report data as an 'application/octet-stream' blob. * * @return {string} jobId The job id for upload. */ function loadDataToBigquery(reportConfig, data) { // Create the data upload job. var job = { configuration: { load: { destinationTable: { projectId: CONFIG.BIGQUERY_PROJECT_ID, datasetId: CONFIG.BIGQUERY_DATASET_ID, tableId: reportConfig.NAME + reportConfig.DATE }, skipLeadingRows: 1 } } }; var insertJob = BigQuery.Jobs.insert(job, CONFIG.BIGQUERY_PROJECT_ID, data); Logger.log('Load job started for %s. Check on the status of it here: ' + 'https://bigquery.cloud.google.com/jobs/%s', reportConfig.NAME, CONFIG.BIGQUERY_PROJECT_ID); return insertJob.jobReference.jobId; } /** * Polls until all jobs are 'DONE'. * * @param {Array.<string>} jobIds The list of all job ids. */ function waitTillJobsComplete(jobIds) { var complete = false; var remainingJobs = jobIds; while (!complete) { if (AdWordsApp.getExecutionInfo().getRemainingTime() < 5){ Logger.log('Script is about to timeout, jobs ' + remainingJobs.join(',') + ' are still incomplete.'); } remainingJobs = getIncompleteJobs(remainingJobs); if (remainingJobs.length == 0) { complete = true; } if (!complete) { Logger.log(remainingJobs.length + ' jobs still being processed.'); // Wait 5 seconds before checking status again. Utilities.sleep(5000); } } Logger.log('All jobs processed.'); } /** * Iterates through jobs and returns the ids for those jobs * that are not 'DONE'. * * @param {Array.<string>} jobIds The list of job ids. * * @return {Array.<string>} remainingJobIds The list of remaining job ids. */ function getIncompleteJobs(jobIds) { var remainingJobIds = []; for (var i = 0; i < jobIds.length; i++) { var jobId = jobIds[i]; var getJob = BigQuery.Jobs.get(CONFIG.BIGQUERY_PROJECT_ID, jobId); if (getJob.status.state != 'DONE') { remainingJobIds.push(jobId); } } return remainingJobIds; } /** * Sends a notification email that jobs have completed loading. * * @param {Array.<string>} jobIds The list of all job ids. */ function sendEmail(jobIds) { var html = []; html.push( '<html>', '<body>', '<table width=800 cellpadding=0 border=0 cellspacing=0>', '<tr>', '<td colspan=2 align=right>', "<div style='font: italic normal 10pt Times New Roman, serif; " + "margin: 0; color: #666; padding-right: 5px;'>" + 'Powered by AdWords Scripts</div>', '</td>', '</tr>', "<tr bgcolor='#3c78d8'>", '<td width=500>', "<div style='font: normal 18pt verdana, sans-serif; " + "padding: 3px 10px; color: white'>Adwords data load to " + "Bigquery report</div>", '</td>', '<td align=right>', "<div style='font: normal 18pt verdana, sans-serif; " + "padding: 3px 10px; color: white'>", AdWordsApp.currentAccount().getCustomerId(), '</tr>', '</table>', '<table width=800 cellpadding=0 border=1 cellspacing=0>', "<tr bgcolor='#ddd'>", "<td style='font: 12pt verdana, sans-serif; " + 'padding: 5px 0px 5px 5px; background-color: #ddd; ' + "text-align: left'>Report</td>", "<td style='font: 12pt verdana, sans-serif; " + 'padding: 5px 0px 5px 5px; background-color: #ddd; ' + "text-align: left'>JobId</td>", "<td style='font: 12pt verdana, sans-serif; " + 'padding: 5px 0px 5x 5px; background-color: #ddd; ' + "text-align: left'>Rows</td>", "<td style='font: 12pt verdana, sans-serif; " + 'padding: 5px 0px 5x 5px; background-color: #ddd; ' + "text-align: left'>State</td>", "<td style='font: 12pt verdana, sans-serif; " + 'padding: 5px 0px 5x 5px; background-color: #ddd; ' + "text-align: left'>ErrorResult</td>", '</tr>', createTableRows(jobIds), '</table>', '</body>', '</html>'); MailApp.sendEmail(CONFIG.RECIPIENT_EMAILS.join(','), 'Adwords data load to Bigquery Complete', '', {htmlBody: html.join('\n')}); } /** * Creates table rows for email report. * * @param {Array.<string>} jobIds The list of all job ids. */ function createTableRows(jobIds) { var html = []; for (var i = 0; i < jobIds.length; i++) { var jobId = jobIds[i]; var job = BigQuery.Jobs.get(CONFIG.BIGQUERY_PROJECT_ID, jobId); var errorResult = '' if (job.status.errorResult) { errorResult = job.status.errorResult; } html.push('<tr>', "<td style='padding: 0px 10px'>" + job.configuration.load.destinationTable.tableId + '</td>', "<td style='padding: 0px 10px'>" + jobId + '</td>', "<td style='padding: 0px 10px'>" + job.statistics.load?job.statistics.load.outputRows:0 + '</td>', "<td style='padding: 0px 10px'>" + job.status.state + '</td>', "<td style='padding: 0px 10px'>" + errorResult + '</td>', '</tr>'); } return html.join('\n'); }
ก่อนเรียกใช้สคริปต์ อย่าลืมคลิกปุ่มดูตัวอย่างที่มุมล่างขวาเพื่อตรวจสอบผลลัพธ์ หากมีข้อผิดพลาด ระบบจะเตือนคุณและระบุว่าเกิดบรรทัดใด ดังในภาพหน้าจอนี้:


หากไม่มีข้อผิดพลาด ให้คลิกปุ่มเรียกใช้:

ด้วยเหตุนี้ คุณจะได้รับรายงาน CLICK_PERFORMANCE_REPORT ใหม่ใน GBQ ของคุณ ซึ่งจะสามารถใช้ได้ในวันถัดไป:

โปรดจำไว้ว่าเมื่อคุณใช้การถ่ายโอนข้อมูล คุณจะได้รับข้อมูลดิบที่ไม่ได้รวมกลุ่มจำนวนมาก ด้วย Ads Script คุณจะมีข้อมูลเกี่ยวกับบางฟิลด์เท่านั้น
ฟิลด์ต่อไปนี้จากการอัปโหลดนี้จะรวมอยู่ในตาราง OWOX BI ที่เกี่ยวข้องกับเซสชัน:
- GclId
- รหัสแคมเปญ
- ชื่อแคมเปญ
- AdGroupId
- ชื่อกลุ่มโฆษณา
- รหัสเกณฑ์
- เกณฑ์พารามิเตอร์
- คีย์เวิร์ดMatchType
วิธีเชื่อมต่อการดาวน์โหลดข้อมูลจาก Google Ads กับ OWOX BI
ตอนนี้ คุณต้องรวมข้อมูลจาก Google Ads กับข้อมูลไซต์เพื่อทำความเข้าใจว่าผู้ใช้เข้าถึงไซต์ของคุณผ่านแคมเปญใดบ้าง ตารางที่คุณได้รับใน BigQuery เช่น การโอนข้อมูล ไม่มีพารามิเตอร์รหัสไคลเอ็นต์ คุณกำหนดได้เฉพาะลูกค้าที่คลิกโฆษณาโดยลิงก์ข้อมูล gclid กับข้อมูลขั้นตอน OWOX BI
หากคุณยังไม่มี Google Analytics → ไปป์ไลน์การสตรีม Google BigQuery ใน OWOX BI โปรดอ่านคำแนะนำในการสร้าง
จากนั้นไปที่โครงการ OWOX BI ของคุณและเปิดไปป์ไลน์นี้ คลิกแท็บการตั้งค่า และภายใต้การรวบรวมข้อมูลเซสชัน คลิกแก้ไขการตั้งค่า:

ใช้แถบเลื่อนเพื่อเปิดใช้งานการรวบรวมข้อมูลสำหรับแคมเปญที่ติดป้ายกำกับอัตโนมัติของ Google Ads แล้วคลิกเปลี่ยนการตั้งค่า:

เลือกประเภทมาร์กอัป AutoLabel ระบุวิธีโหลดสคริปต์การโอนข้อมูลหรือโฆษณาไปยัง BigQuery ระบุโปรเจ็กต์และชุดข้อมูลที่จะดาวน์โหลดข้อมูล Google Ads และบันทึกการตั้งค่าของคุณ:

เคล็ดลับที่เป็นประโยชน์
เคล็ดลับ 1. ด้วยการโอนข้อมูล คุณสามารถอัปโหลดข้อมูลย้อนหลังจาก Google Ads ไปยัง GBQ ในเวลาเดียวกัน ไม่มีการจำกัดระยะเวลาในการโหลดทั้งหมด (หนึ่งปีหรือสามปี) แต่มีข้อมูลครั้งละ 180 วันเท่านั้น
คุณสามารถเปิดใช้งานการอัปโหลดและระบุระยะเวลาโดยใช้ปุ่มกำหนดเวลาทดแทนบนแท็บการโอนโดยเลือกการโอนที่คุณต้องการ:

เคล็ดลับที่ 2 หากคุณต้องการตรวจสอบจำนวนบัญชี Google Ads ที่จะเรียกเก็บเงินจาก GCP คุณต้องกำหนดจำนวน ExternalCustomerID ในตารางลูกค้าโดยใช้คำค้นหา:
SELECT ExternalCustomerId FROM `project_name.dataset_name.Customer_*` WHERE _PARTITIONTIME >= "2020-01-01 00:00:00" AND _PARTITIONTIME < "2020-07-10 00:00:00" group by 1
SELECT ExternalCustomerId FROM `project_name.dataset_name.Customer_*` WHERE _PARTITIONTIME >= "2020-01-01 00:00:00" AND _PARTITIONTIME < "2020-07-10 00:00:00" group by 1
คุณสามารถแก้ไขวันที่ในแบบสอบถาม
เคล็ดลับ 3. คุณสามารถเข้าถึงข้อมูลที่อัพโหลดได้ด้วยตัวเองโดยใช้คำสั่ง SQL ตัวอย่างเช่น นี่คือข้อความค้นหาเพื่อกำหนดประสิทธิภาพของแคมเปญจากตาราง "แคมเปญ" และ "CampaignBasicStats" ที่ได้รับจากการโอนข้อมูล
SELECT {source language="sql"} c.ExternalCustomerId, c.CampaignName, c.CampaignStatus, SUM(cs.Impressions) AS Impressions, SUM(cs.Interactions) AS Interactions, {/source} (SUM(cs.Cost) / 1000000) AS Cost FROM `[DATASET].Campaign_[CUSTOMER_ID]` c LEFT JOIN {source language="sql"} {source language="sql"} `[DATASET].CampaignBasicStats_[CUSTOMER_ID]` cs ON (c.CampaignId = cs.CampaignId AND cs._DATA_DATE BETWEEN DATE_ADD(CURRENT_DATE(), INTERVAL -31 DAY) AND DATE_ADD(CURRENT_DATE(), INTERVAL -1 DAY)) WHERE c._DATA_DATE = c._LATEST_DATE GROUP BY 1, 2, 3 ORDER BY Impressions DESC
SELECT {source language="sql"} c.ExternalCustomerId, c.CampaignName, c.CampaignStatus, SUM(cs.Impressions) AS Impressions, SUM(cs.Interactions) AS Interactions, {/source} (SUM(cs.Cost) / 1000000) AS Cost FROM `[DATASET].Campaign_[CUSTOMER_ID]` c LEFT JOIN {source language="sql"} {source language="sql"} `[DATASET].CampaignBasicStats_[CUSTOMER_ID]` cs ON (c.CampaignId = cs.CampaignId AND cs._DATA_DATE BETWEEN DATE_ADD(CURRENT_DATE(), INTERVAL -31 DAY) AND DATE_ADD(CURRENT_DATE(), INTERVAL -1 DAY)) WHERE c._DATA_DATE = c._LATEST_DATE GROUP BY 1, 2, 3 ORDER BY Impressions DESC
PS หากคุณต้องการความช่วยเหลือในการอัปโหลดและผสานข้อมูลลงใน Google BigQuery เราพร้อมที่จะช่วยเหลือ ลงทะเบียนสำหรับการสาธิต — และเราจะพูดถึงรายละเอียด