3

I run following request in MySQL and it works, but results in an error with bigquery standard SQL.

$sql = <<<EOT
 SELECT
 ads.ad_id,
 (SELECT count(*)
 FROM `PRFXvisits` AS v
 INNER JOIN `PRFXvisit_data` AS vd
 ON vd.visit_id = v.id
 WHERE v.date_time >= @xday AND v.date_time < @xdaytomorrow
 AND ads.id = vd.ad_id
 ) AS clicks
 FROM `PRFXad_reports` AS r
 INNER JOIN `PRFXads` AS ads
 ON r.ad_id = ads.id
 WHERE r.rdate = @xday AND ads.is_archive = 0
 GROUP BY ads.ad_id
 ORDER BY ads.ad_id ASC;
EOT;

Error message:

{
 "error": {
 "errors": [
 {
 "domain": "global",
 "reason": "invalidQuery",
 "message": "WHERE clause expression references ads.id which is neither grouped nor aggregated at [8:15]",
 "locationType": "other",
 "location": "query"
 }
 ],
 "code": 400,
 "message": "WHERE clause expression references ads.id which is neither grouped nor aggregated at [8:15]"
 }
}

If I replace ads.id with e.g. 380 no error is produced.

 $sql = <<<EOT
 SELECT
 ads.ad_id,
 (SELECT count(*)
 FROM `PRFXvisits` AS v
 INNER JOIN `PRFXvisit_data` AS vd
 ON vd.visit_id = v.id
 WHERE v.date_time >= @xday AND v.date_time < @xdaytomorrow
 AND 380 = vd.ad_id
 ) AS clicks
 FROM `PRFXad_reports` AS r
 INNER JOIN `PRFXads` AS ads
 ON r.ad_id = ads.id
 WHERE r.rdate = @xday AND ads.is_archive = 0
 GROUP BY ads.ad_id
 ORDER BY ads.ad_id ASC;
EOT;

Why can't I reference ads.id in the inner select from outer FROM clause in bigquery?

It seems mysql select random row to show ads.id during grouping by ads.ad_id.

Rick James
80.7k5 gold badges52 silver badges119 bronze badges
asked Mar 1, 2018 at 12:11
3
  • Why do you need the GROUP BY ads.ad_id in the main query? Do you get error if you remove it? Commented Mar 1, 2018 at 13:29
  • If i remove GROUP BY there will be duplicates: e.g. (ad_id: 2500989, clicks: 2414, ) (ad_id: 2500989, clicks: 2414, ) Commented Mar 2, 2018 at 15:42
  • Yes, I figured that, that's why I turned the join into an EXISTS subquery in my answer/ Commented Mar 2, 2018 at 15:46

1 Answer 1

2

Try removing the GROUP BY from the main query and converting the join to PRFXad_reports to an EXISTS subquery:

SELECT
 ads.ad_id,
 ( SELECT count(*)
 FROM `PRFXvisits` AS v
 INNER JOIN `PRFXvisit_data` AS vd
 ON vd.visit_id = v.id
 WHERE v.date_time >= @xday AND v.date_time < @xdaytomorrow
 AND ads.id = vd.ad_id
 ) AS clicks
FROM `PRFXads` AS ads
WHERE ads.is_archive = 0
 AND EXISTS
 ( SELECT 1
 FROM `PRFXad_reports` AS r
 WHERE r.ad_id = ads.id
 AND r.rdate = @xday
 )
ORDER BY ads.ad_id ;
answered Mar 1, 2018 at 13:33
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.