Can I use WHERE clause after JOIN USING in snowflake?

Viewed 1549

Can I use WHERE after

JOIN USING?

In my case if I run on snowflake multiple times the same code:

with CTE1 as
(
select * 
from A
left join B 
on A.date_a = B.date_b
)
select * 
from CTE1
inner join C 
using(var1_int)
where CTE1.date_a >= date('2020-10-01')
limit 1000;

sometimes I get a result and sometimes i get the error:

SQL compilation error: Can not convert parameter 'DATE('2020-10-01')' of type [DATE] into expected type [NUMBER(38,0)]

where NUMBER(38,0) is the type of var1_int column

2 Answers

Your problem has nothing to do with the existence of a where clause. Of course you can use a where clause after joins. That is how SQL queries are constructed.

According to the error message, CTE1.date_a is a number. Comparing it to a date results in a type-conversion error. If you provided sample data and desired results, then it might be possible to suggest a way to fix the problem.

tl;dr: Instead of JOIN .. USING() always prefer JOIN .. ON.


You are right to be suspicious of the results. Given your staging, only one of these queries returns without errors:

select a.date_1, id_1
from AE_USING_TST_A a
left join AE_USING_TST_B b 
on a.date_1 = b.date_2
join AE_USING_TST_C v
using(id_1)
where A.date_1 >= date('2020-10-01')

-- Can not convert parameter 'DATE('2020-10-01')' of type 
-- [DATE] into expected type [NUMBER(38,0)]
;


select a.date_1, a.id_1
from AE_USING_TST_A a
left join AE_USING_TST_B b 
on a.date_1 = b.date_2
join AE_USING_TST_C v
on a.id_1=v.id_1
where A.date_1 >= date('2020-10-01')

-- 2020-10-11   2
;

I would call this a bug, except that the documentation is clear about not doing this kind of queries with JOIN .. USING:

To use the USING clause properly, the projection list (the list of columns and other expressions after the SELECT keyword) should be “*”. This allows the server to return the key_column exactly once, which is the standard way to use the USING clause. For examples of standard and non-standard usage, see the examples below.

https://docs.snowflake.com/en/sql-reference/constructs/join.html

The documentation doubles down on the problems of using USING() on non-standard situations, with a different query acting "wrong":

The following example shows non-standard usage; the projection list contains something other than “*”. Because the usage is non-standard, the output contains two columns named “userid”, and the second occurrence (which you might expect to contain a value from table ‘r’) contains a value that is not in the table (the value ‘a’ is not in the table ‘r’).

So just prefer JOIN .. ON. For extra discussion on the SQL ANSI standard not defining behavior for some cases of USING() check:

Related