Q:

Display default value if query results in no records in BigQuery

A query can return an empty table on BigQuery. An example of such occurrence is if I join a bunch of tables in a query on BigQuery and the result of the joins is an empty table, or if there are no matches based on the where clause.
Here is a dumb sample query that will always return in an empty join:
#standardSQL
WITH query1 AS (
    SELECT 1 AS number, "one" AS message
), query2 AS (
    SELECT 2 AS number, "two" AS message)
SELECT "query result" AS result, query1.* 
FROM query1
JOIN query2 ON query1.number = query2.number;

The query will show this output: Query returned zero records.
If that's the case I want to return either a message or a default row. But I don't know how to do that. I've tried using IFNULL, but that's only usuable for one column, not number of columns. Using an IF statement gave me errors as you can't return row(s) from an if statement.
I think the error it gave me was Scalar subquery cannot have more than one column unless using SELECT AS STRUCT to build STRUCT values.
Another thing that I could think of, but don't know how to implement is to add a UNION at the end that would only trigger if the previous parts didn't return anything. Or wrap the existing query in a WITH statement subquery and if that returns nothing, print a message, else do SELECT * FROM sub_query.
I'd like to either just display a message when an empty table is the result, or return a row with some default values.
I understand the answer is likely to contain a UNION statement and hence displaying just a message won't be possible. In that case I'd like to display a default row instead. For the above sample query a default row would look like: "No results found", NULL, NULL.
When the query returns a non empty table, I want it to look exactly like it did with the original query. So there shouldn't be any added columns or change to the schema of the result. 

A:

You would use union all.  Something like this:
with t as (
      . . . <all your query stuff here>
     )
select cast(NULL as string) as msg, t.*
from t
union all
select msg, t.*  -- all the `t` columns will be `NULL`
from (select 'No rows returned' as msg) left join
     t
     on 1 = 0  -- always false
where not exists (select 1 from t);

Note the complications.  A query returns a fixed set of columns with a fixed set of names.  This version returns an extra column at the beginning of the data to contain the message.  In order to get all the rest of the columns, a left join is used, but the on clause is always false.

A:

Option 1   
Below displays row with all nulls in case if there is no result returned for your_query      
#standardSQL
WITH your_query AS ( ... )
SELECT * FROM your_query 
UNION ALL 
SELECT your_query.* REPLACE ("No results found" AS result)
FROM (SELECT 1) 
LEFT JOIN your_query ON FALSE
WHERE NOT EXISTS (SELECT 1 FROM your_query)  

Row result              number  message  
1   No results found    null    null     

Option 2   
If you know in advance output schema - below returns default row (assuming 0 default for number and "none" default for message 
#standardSQL
WITH your_query AS ( ... )
SELECT * FROM your_query 
UNION ALL 
SELECT "No results found", 0, "none" FROM (SELECT 1) 
LEFT JOIN your_query ON FALSE
WHERE NOT EXISTS (SELECT 1 FROM your_query)

Row result              number  message  
1   No results found    0       none     

