2017-01-03 4 views
1

Wie kann ich zwei Tabellen in einer SELECT-Anweisung verbinden, in der ich auch eine UDF verwende? Ich habe die SQL-Abfrage und die UDF-Funktion in zwei Dateien gespeichert, die ich über die bq-Befehlszeile aufruft. Allerdings, wenn ich es laufen, bekomme ich folgende Fehlermeldung:BigQuery Join und UDF

BigQuery error in query operation: Error processing job '[projectID]:bqjob_[error_number]': Table name cannot be resolved: dataset name is missing.

Bitte beachte, dass ich im richtigen Projekt über die gcloud Auth Methode angemeldet bin. My SQL-Anweisung:

SELECT 
    substr(date,1,6) as date, 
    device, 
    channelGroup, 
    COUNT(DISTINCT CONCAT(fullVisitorId,cast(visitId as string))) AS sessions, 
    COUNT(DISTINCT fullVisitorId) AS users, 
FROM 
    defaultChannelGroup(
    SELECT 
     a.date, 
     a.device.deviceCategory AS device, 
     b.hits.page.pagePath AS page, 
     a.fullVisitorId, 
     a.visitId, 
     a.trafficSource.source AS trafficSourceSource, 
     a.trafficSource.medium AS trafficSourceMedium, 
     a.trafficSource.campaign AS trafficSourceCampaign 
    FROM FLATTEN(
     SELECT date,device.deviceCategory,trafficSource.source,trafficSource.medium,trafficSource.campaign,fullVisitorId,visitID 
     FROM 
     TABLE_DATE_RANGE([datasetname.ga_sessions_],TIMESTAMP('2016-10-01'),TIMESTAMP('2016-10-31')) 
    ,hits) as a 
    LEFT JOIN FLATTEN(
     SELECT hits.page.pagePath,hits.time,visitID,fullVisitorId 
     FROM 
     TABLE_DATE_RANGE([datasetname.ga_sessions_],TIMESTAMP('2016-10-01'),TIMESTAMP('2016-10-31')) 
     WHERE 
     hits.time = 0 
     and trafficSource.medium = 'organic' 
    ,hits) as b 
    ON a.fullVisitorId = b.fullVisitorId AND a.visitID = b.visitID 
) 
GROUP BY 
    date, 
    device, 
    channelGroup 
ORDER BY sessions DESC 

, wo ich meinen Datensatznamen mit dem richtigen Namen natürlich ersetzt; und einige der UDF (die mit einer anderen Abfrage funktioniert):

function defaultChannelGroup(row, emit) 
{ 
    function output(channelGroup) { 
    emit({channelGroup:channelGroup, 
     fullVisitorId: row.fullVisitorId, 
     visitId: row.visitId, 
     device: row.device, 
     date: row.date 
     }); 
    } 
    computeDefaultChannelGroup(row, output); 
} 

bigquery.defineFunction(
    'defaultChannelGroup', 
    ['date', 'device', 'page', 'trafficSourceMedium', 'trafficSourceSource', 'trafficSourceCampaign', 'fullVisitorId', 'visitId'], 
    //['device', 'page', 'trafficSourceMedium', 'trafficSourceSource', 'trafficSourceCampaign', 'fullVisitorId', 'visitId'], 
    [{'name': 'channelGroup', 'type': 'string'}, 
    {'name': 'fullVisitorId', 'type': 'string'}, 
    {'name': 'visitId', 'type': 'integer'}, 
    {'name': 'device', 'type': 'string'}, 
    {'name': 'date', 'type': 'string'} 
], 
    defaultChannelGroup 
); 
+0

Ich konnte nicht reproduzieren. (Einige BigQuery-Teammitglieder könnten sich auch das Protokoll ansehen, wenn Sie auch Ihre vollständige Job-ID hinterlassen) –

+0

Danke @FelipeHoffa. Ich ran es heute Morgen über den folgenden Befehl: 'bq Abfrage --udf_resource = Desktop/bq.js" $ (Katze Desktop/bq-sd-mkt-channels.sql) "' und bekam die gleiche Fehlermeldung, dh : 'bqjob_r324a276c6f5130bc_000001596949a59f_1 ': Tabellenname kann nicht aufgelöst werden: Dateiname fehlt' – kekchoze

Antwort

1

Die select-Anweisungen innerhalb der abflachen Funktion in Klammern sein muß.

BQ-Befehl in der Shell-Ran: bq query --udf_resource=udf.js "$(cat query.sql)"

query.sql enthält die folgenden Scripts:

SELECT 
    substr(date,1,6) as date, 
    device, 
    channelGroup, 
    COUNT(DISTINCT CONCAT(fullVisitorId,cast(visitId as string))) AS sessions, 
    COUNT(DISTINCT fullVisitorId) AS users, 
    COUNT(DISTINCT transactionId) as orders, 
    CAST(SUM(transactionRevenue)/1000000 AS INTEGER) as sales 
FROM 
    defaultChannelGroup(
    SELECT 
     a.date as date, 
     a.device.deviceCategory AS device, 
     b.hits.page.pagePath AS page, 
     a.fullVisitorId as fullVisitorId, 
     a.visitId as visitId, 
     a.trafficSource.source AS trafficSourceSource, 
     a.trafficSource.medium AS trafficSourceMedium, 
     a.trafficSource.campaign AS trafficSourceCampaign, 
     a.hits.transaction.transactionRevenue as transactionRevenue, 
     a.hits.transaction.transactionID as transactionId 
    FROM FLATTEN((
     SELECT date,device.deviceCategory,trafficSource.source,trafficSource.medium,trafficSource.campaign,fullVisitorId,visitID, 
       hits.transaction.transactionID, hits.transaction.transactionRevenue 
     FROM 
     TABLE_DATE_RANGE([datasetname.ga_sessions_],TIMESTAMP('2016-10-01'),TIMESTAMP('2016-10-31')) 
    ),hits) as a 
    LEFT JOIN FLATTEN((
     SELECT hits.page.pagePath,hits.time,trafficSource.medium,visitID,fullVisitorId 
     FROM 
     TABLE_DATE_RANGE([datasetname.ga_sessions_],TIMESTAMP('2016-10-01'),TIMESTAMP('2016-10-31')) 
     WHERE 
     hits.time = 0 
     and trafficSource.medium = 'organic' 
    ),hits) as b 
    ON a.fullVisitorId = b.fullVisitorId AND a.visitID = b.visitID 
) 
GROUP BY 
    date, 
    device, 
    channelGroup 
ORDER BY sessions DESC 

udf.js und enthält die folgende Funktion (die Funktion ist 'computeDefaultChannelGroup' nicht enthalten):

function defaultChannelGroup(row, emit) 
{ 
    function output(channelGroup) { 
    emit({channelGroup:channelGroup, 
     date: row.date, 
     fullVisitorId: row.fullVisitorId, 
     visitId: row.visitId, 
     device: row.device, 
     transactionId: row.transactionId, 
     transactionRevenue: row.transactionRevenue, 
     }); 
    } 
    computeDefaultChannelGroup(row, output); 
} 

bigquery.defineFunction(
    'defaultChannelGroup', 
    ['date', 'device', 'page', 'trafficSourceMedium', 'trafficSourceSource', 'trafficSourceCampaign', 'fullVisitorId', 'visitId', 'transactionId', 'transactionRevenue'], 
    [{'name': 'channelGroup', 'type': 'string'}, 
    {'name': 'date', 'type': 'string'}, 
    {'name': 'fullVisitorId', 'type': 'string'}, 
    {'name': 'visitId', 'type': 'integer'}, 
    {'name': 'device', 'type': 'string'}, 
    {'name': 'transactionId', 'type': 'string'}, 
    {'name': 'transactionRevenue', 'type': 'integer'} 
], 
    defaultChannelGroup 
); 

lief ohne Fehler und stimmte die Daten in Google Analytics überein.