Im trying to join two tables with a left join but, the next error comes out:
error line 7 at position 11 invalid identifier 'VAR01'
This is my query
SELECT
CU.X||CU.Y||CU.Z AS VAR01,
RE.VAR02,
*
FROM TABLE01 CU
LEFT JOIN TABLE02 RE
ON VAR01 = RE.VAR02
LIMIT 10
I know that the Invalid identifiers implies to me something is named incorrectly, but all the variables that Im using are correct
I could not reproduce this case:
CREATE OR REPLACE TABLE TABLE01(X TEXT, Y TEXT, Z TEXT)
AS SELECT 'a', 'b', 'c'
UNION SELECT 'x', 'y', 'z'
UNION SELECT 'i', 'j', 'k';
CREATE OR REPLACE TABLE TABLE02(VAR02 TEXT)
AS SELECT 'abc'
UNION SELECT 'ijk';
SELECT
CU.X||CU.Y||CU.Z AS VAR01,
RE.VAR02,
*
FROM TABLE01 CU
LEFT JOIN TABLE02 RE
ON VAR01 = RE.VAR02
LIMIT 10;
Query profile:
EXPLAIN USING TABULAR
SELECT
CU.X||CU.Y||CU.Z AS VAR01,
RE.VAR02,
*
FROM TABLE01 CU
LEFT JOIN TABLE02 RE
ON VAR01 = RE.VAR02
LIMIT 10;
Looks like you were missing the alias from your first table before the column name. Your join was trying to join on
ON VAR01 = RE.VAR02
You need the table alias before the VAR01, see below:
SELECT
CU.X||CU.Y||CU.Z AS VAR01,
RE.VAR02,
*
FROM TABLE01 CU
LEFT JOIN TABLE02 RE
ON CU.VAR01 = RE.VAR02
LIMIT 10
This is because the ON clause is evaluated before the SELECT clause, so the alias VAR01 does not yet exist at the time the ON clause is being evaluated.
You can do it either way :
1) Repeat the expression in the ON clause :
SELECT
CU.X||CU.Y||CU.Z AS VAR01,
RE.VAR02,
*
FROM TABLE01 CU
LEFT JOIN TABLE02 RE
ON CU.X||CU.Y||CU.Z = RE.VAR02
LIMIT 10;
2) Using Subquery:
SELECT *
FROM (
SELECT
CU.X||CU.Y||CU.Z AS VAR01,
RE.VAR02,
*
FROM TABLE01 CU
LEFT JOIN TABLE02 RE
ON CU.X||CU.Y||CU.Z = RE.VAR02
LIMIT 10
) subquery;
Related
I have two tables with similar columns and I would like to know the difference between these tables. So if all values (column-wise) of the row exists in both table it is fine (I do not want to see this), while I want to see all rows that.
I have tried this:
select m.*, t.*
from test.test1 m
full outer join test.test2 t
on row(m) = row(t)
where m.date = '2022-11-01'
but I am getting all rows only from the first table. Note. I want only one query (no subqueries)
You need to add the null check for your key columns in the where statement:
select m.*, t.*
from test.test1 m
full outer join test.test2 t
on row(m) = row(t)
where m.KEY is null or t.KEY is null and m.date = '2022-11-01'
You can use the EXCEPT/EXCEPT ALL set operators to compare tables with the column layout (data-types and order of columns (if using SELECT *) must match).
SELECT 'IN TEST1 but not in TEST2' as SRC, EA.*
FROM (
SELECT *
FROM test.test1 m
where m.date='2022-11-01'
EXCEPT ALL
SELECT *
FROM test.test2
) EA
union all
SELECT 'IN TEST2 but not in TEST1' as SRC, EA.*
FROM (
SELECT *
FROM test.test2
EXCEPT ALL
SELECT *
FROM test.test1 m
where m.date='2022-11-01'
) EA
I ran across a join style I had not seen before in this question:
UPDATE SomeTable
SET CurrentStatusID = [Status].[ID]
FROM SomeTable
RIGHT JOIN [Status] ON [Name] = 'Acknowledged'
WHERE SomeTable.[ID] = #SomeID
Can someone explain this? It seems to be a shortcut for a typically join. In other words:
Select * from Items
JOIN ItemTypes on Code = 'TASK'
is a shortcut for:
Select * from Items i
JOIN ItemTypes it on i.ItemTypeId = it.Id
where it.Code = 'TASK'
Is that correct? Or am I missing something?
Incorrect, it is not a shortcut, at least not the one you think (to be precise: an INNER JOIN written like this could be considered a shortcut for a CROSS JOIN + WHERE here but I advise you to avoid thinking this is it).
In any type of JOIN, you are actually allowed to use constants, not only columns and for OUTER JOIN, the result will be different depending on where you write things.
Consider the following 2 examples:
WITH TableA(ID) AS (
SELECT 1
UNION
SELECT 2
), TableB(ID, Type) AS (
SELECT 1, 'Type1'
UNION
SELECT 1, 'Type2'
UNION
SELECT 2, 'Type2'
)
SELECT *
FROM TableA
LEFT OUTER JOIN TableB ON TableA.ID = TableB.ID
WHERE Type= 'Type1'
And
WITH TableA(ID) AS (
SELECT 1
UNION
SELECT 2
), TableB(ID, Type) AS (
SELECT 1, 'Type1'
UNION
SELECT 1, 'Type2'
UNION
SELECT 2, 'Type2'
)
SELECT *
FROM TableA
LEFT OUTER JOIN TableB ON TableA.ID = TableB.ID AND Type= 'Type1'
The first sample says: join everything but return only records containing Type1.
The second sample says: join only when you have Type1 on the right but return everything, even if you have failed to join (LEFT OUTER JOIN)
I have the following query in BigQuery:
#Standard SQL
SELECT *
FROM `Table_1`
LEFT JOIN `Table_2` ON (timestamp BETWEEN TimeStampStart AND TimeStampEnd)
But I get the following Error:
Error: LEFT OUTER JOIN cannot be used without a condition that is an equality of fields from both sides of the join.
If I use JOIN instead of LEFT JOIN, it works, but I want to keep all the rows from Table_1 (so also the ones which aren't matched to Table_2)
How to achieve this?
This is absolutely stupid... but the same query will work if you add a condition that matches a column from table1 with a column from table2:
WITH Table_1 AS (
SELECT CAST('2018-08-15' AS DATE) AS Timestamp, 'Foo' AS Foo
UNION ALL
SELECT CAST('2018-09-15' AS DATE), 'Foo'
), Table_2 AS (
SELECT CAST('2018-08-14' AS DATE) AS TimeStampStart, CAST('2018-08-16' AS DATE) AS TimeStampEnd, 'Foo' AS Bar
)
SELECT *
FROM Table_1
LEFT JOIN Table_2 ON Table_1.Foo = Table_2.Bar AND Table_1.Timestamp BETWEEN Table_2.TimeStampStart AND Table_2.TimeStampEnd
See if you have additional matching criteria that you can use (like another column that links table1 and table2 on equality).
A LEFT JOIN is always equivalent to the UNION of :
the INNER JOIN between the same two arguments on the same join predicate, and
the set of rows from the first argument for which no matching row is found (and properly extended with null values for all columns retained from the second argument)
That latter portion can be written as
SELECT T1.*, null as T2_C1, null as T2_C2, ...
FROM T1
WHERE NOT EXISTS (SELECT * FROM T2 WHERE )
So if you spell out the UNION you should be able to get there.
Interesting. This works for me in standard SQL:
select *
from (select 1 as x) a left join
(select 2 as a, 3 as b) b
on a.x between b.a and b.b
I suspect you are using legacy SQL. Such switch to standard SQL. (And drop the parentheses after the between.)
The problem is:
#(Standard SQL)#
This doesn't do anything. Use:
#StandardSQL
Hi as per the documentation, "(" has a special meaning, so please try without the brackets.
SELECT * FROM Table_1
LEFT JOIN Table_2 ON Table_1.timestamp >= Table_2.TimeStampStart AND Table_1.timestamp <= Table_2.TimeStampEnd
Documentation here
These queries both get results:
SELECT * FROM Table1 WHERE Criteria = '5'
SELECT * FROM Table1 WHERE Criteria = '3'
This query gets results:
SELECT *
FROM Table1 p, Table2 m
WHERE p.UID = m.ID
AND Criteria = '5'
This query does not:
SELECT *
FROM Table1 p, Table2 m
WHERE p.UID = m.ID
AND Criteria = '3'
I am trying to convert these to a proper join which returns results even if there are no records in the right table.
I have tried the following
SELECT *
FROM Table1 p LEFT JOIN Table2 m ON p.UID = m.ID
WHERE p.Criteria = '3'
AND m.OtherCriteria = 'Moron'
--0 results
My limited understanding was that LEFT join is what I needed. I want data from the left table even if there is no data in the right table that matches. Since this didn't work I also tried right join, left outer join, right outer join and full join. None returned results.
What am I missing?
This is too long for a comment. Your query:
SELECT *
FROM Table1 p LEFT JOIN
Table2 m
ON p.UID = m.ID AND p.Criteria = '3';
Should be returning a row for all rows in table1. If there is no match, then the values will be NULL for table2. This is easily demonstrated: Here is a MySQL example on SQL Fiddle. Because this is standard behavior, it should work on almost any database.
Note that this query is quite different from this one:
SELECT *
FROM Table1 p LEFT JOIN
Table2 m
ON p.UID = m.ID
WHERE p.Criteria = '3';
This query returns no rows, because no rows match the WHERE clause. The filtering happens (conceptually) after the LEFT JOIN.
I changed the code in the SQL Fiddle slightly, so that query is:
select *
from (select 5 as criteria, 1 as id union all
select 6, 1 union all
select 7, 2
) table1 left join
(select 1 as id, 'x' as x
) table2
on table1.id = table2.id and criteria = 3;
As a note: you should always use explicit join syntax. Simple rule: Never use commas in the FROM clause.
If your database is returning no rows, then it is behaving in a non-standard manner or your interface has decided to filter the rows for some reason.
While we try to join between union tables on one side with other table on the other side,
SELECT A.x,B.y FROM ([DataSet.Liad],[DataSet.Livne]) AS A INNER JOIN [DataSet.Names] AS B ON A.ID = B.ID LIMIT 10
we get this error:
Error: 2.1 - 0.0: JOIN cannot be applied directly to a table union or to a table wildcard function. Consider wrapping the table union or table wildcard function in a subquery (e.g., SELECT *).
In order to solve this error I suggest you to use a View.
Save this Query of union as a View, DataSet.LiadLivne:
SELECT * FROM [DataSet.Liad],[DataSet.Livne]
Execute the origin query using the view:
SELECT A.x,B.y FROM [DataSet.LiadLivne] AS A INNER JOIN [DataSet.Names] AS B ON A.ID = B.ID LIMIT 10
Enjoy
You need to write as:
SELECT A.x,
B.y
FROM
(SELECT A.x
FROM ([DataSet.Liad],[DataSet.Livne])) AS A
INNER JOIN [DataSet.Names] AS B ON A.ID = B.ID LIMIT 10