SQL JOIN with OPENQUERY - sql

How do I correctly join a query with a open query?
Here is a how my query is layed out right now. The query that is part of the OPENQUERY works by itself.
Select d.* from db.dbo.table d
left join (select * from OPENQUERY(otherSource,'
--working query
SELECT...
left join...
inner join..') OQ
ON d.col1 = OQ.col1
I am catching the error 'Incorrect syntax near 'ON'.

This syntax worked for me:
select
a.id, b.ItemId, a.Name, b.[Description]
from
[A_Database]..tblA a
inner join
openquery([linkedServerDbName], 'select * from [B_Database]..[TableToJoin]') b
ON
a.id = b.ItemId

You may have to reverse it, do your SELECT from the OPENQUERY. So something like:
SELECT * FROM OPENQUERY(remotesource,'SELECT blahblah from tableA) A
RIGHT JOIN tableB B ON B.col1 = A.col1

Related

Oracle to SQL Server conversion error

I have a particular condition in oracle which I am trying to run in MS SQL Server, but having issues..
Here is the code...
select a.*,b.*
from a
left join b on a.id = b.id
and (a.id,b.name) in
( select distinct id,name
from master where record = 'Active')
I am getting the error in line 3 where it says:
An expression of non-boolean type specified in a context where a
condition is expected, near ','.
Pls help
You need to rewrite that into an EXISTS condition:
select a.*,b.*
from a
left join b on a.id = b.id
and exists (select *
from master m
where m.record = 'Active'
and m.id = a.id
and m.name = b.name)
You can't write like this (a.id,b.name)
select a.*,b.*
from a
left join b on a.id = b.id
and a.id in
( select distinct id
from master where record = 'Active')
and b.name in ( select distinct name
from master where record = 'Active')

Please help - SQL Join query

I am working on a project, and need to join results from 2 tables into one set.
The tables are ordered as such:
gameData: [Id,TeamID, data..........]
players: [Id (same as above), name, data.....]
I need to do something like:
SELECT * FROM gameData and SELECT data FROM players WHERE gameData.Id = players.Id
And here is what I have thusfar.
SELECT * FROM gameData AS A LEFT OUTER JOIN players AS B on A.playerID = B.Id;
And have it return all of the values from A, and only the data from B.
I know that the syntax is not correct, I have little experience working with SQL Joins, any advice would be greatly appreciated!
Edit: Trying both answers now. Thanks!
Edit2: Can I do something like: "Select a.* from tableA as a"
I love you guys, working as intended now!
Thanks!
The query I ended up using was:
Select a.*, b.height, b.weight from gameData as a LEFT OUTER JOIN players b on a.playerID = b.Id;
You could enumerate the fields that you select and alias the tables, like:
select a.Id, a.TeamId, a.data, b.data
from tableA a
join tableB b on a.Id = b.Id
Select a.Id, a.TeamID, a.data, b.data
FROM gameData as a
LEFT OUTER JOIN
players b On a.ID = b.ID

How can you perform a join when also using a comma-separated list of tables in an SQL select statement?

This is evidently correct syntax in SQL Server:
SELECT a.id, b.name
FROM Table1 a, Table2 b
WHERE a.id = b.fk1
So is this:
SELECT a.id, c.status
FROM Table1 a
JOIN Table3 c ON a.id = c.fk2
But this apparently isn't:
SELECT a.id, b.name, c.status
FROM Table1 a, Table2 b
JOIN Table3 c ON a.id = c.fk2
WHERE a.id = b.fk1
I would NOT normally want to construct a query in the third case's style (and really not the first case's either), but it would probably be the path of least resistence in editing some code that's already been written at my company. Somebody used the first form with five different tables, and I really need to work in a sixth table through a JOIN statement, without taking chances of messing up what they already have. Even though I could re-write their stuff outright if I need to, I would really like to know how to do something like in the third case.
Running the code exactly as-is in the examples, the third case gives me this error message:
The multi-part identifier "a.id" could not be bound.
What is syntactically breaking the third case? What simple fix could be applied? Thanks!
I, likewise, would not recommend doing this. But, you can just change the , to a cross join:
SELECT a.id, b.name, c.status
FROM Table1 a cross join Table2 b
JOIN Table3 c ON a.id = c.fk2
WHERE a.id = b.fk1
This code:
SELECT a.id, b.name, c.status
FROM Table1 a, Table2 b
JOIN Table3 c ON a.id = c.fk2
WHERE a.id = b.fk1
is doing a cross join on a and the result of an inner join on b and c. c cannot access any of the fields in a because the join is being performed on b. what you should do is change your query to:
SELECT a.id, b.name, c.status
FROM Table1 a
inner join Table2 b on a.id = b.fk1
inner JOIN Table3 c ON a.id = c.fk2

Why does this left join not seem to work as expected?

This came up at work and this really just seems like a puzzle...
Query 1:
SELECT * FROM
SYSIBM.SYSTABLES A LEFT JOIN
SYSIBM.SYSTABLESPACE B
ON A.DBNAME = B.DBNAME
AND A.TSNAME = B.NAME
AND A.TSNAME LIKE 'HIB%'
;
This query does NOT filter on the HIB% criteria, contrary to what it LOOKS like the query should be doing. I would THINK that putting that criteria in the JOIN should deliver identical results.
Query 2 works as expected:
SELECT * FROM
(SELECT * FROM SYSIBM.SYSTABLES
WHERE TSNAME LIKE 'HIB%') A
LEFT JOIN
SYSIBM.SYSTABLESPACE B
ON A.DBNAME = B.DBNAME
AND A.TSNAME = B.NAME
;
What is wrong with the first query?
TRY
SELECT * FROM SYSIBM.SYSTABLES A
LEFT JOIN SYSIBM.SYSTABLESPACE B
ON A.DBNAME = B.DBNAME AND A.TSNAME = B.NAME
WHERE A.TSNAME LIKE 'HIB%' ;
When you put the condition in the left join that is used to filter the records for the join, but since is a left join it is returning all the records from table A becasue you put no conditions on that.
Now it would have been different if the condition was on table B. The it belongs in the left join (unless it is something like B.id is null) or you will turn the query back into an inner join.
Have you tried to move the "Like"-part to a where clause?
SELECT *
FROM SYSIBM.SYSTABLES A
LEFT JOIN SYSIBM.SYSTABLESPACE B ON A.DBNAME = B.DBNAME AND A.TSNAME = B.NAME
WHERE A.TSNAME LIKE 'HIB%'
;

Simulate a left join without using "left join"

I need to simulate the left join effect without using the "left join" key.
I have two tables, A and B, both with id and name columns. I would like to select all the dbids on both tables, where the name in A equals the name in B.
I use this to make a synchronization, so at the beginning B is empty (so I will have couples with id from A with a value and id from B is null). Later I will have a mix of couples with value - value and value - null.
Normally it would be:
SELECT A.id, B.id
FROM A left join B
ON A.name = B.name
The problem is that I can't use the left join and wanted to know if/how it is possible to do the same thing.
you can use this approach, but you must be sure that the inner select only returns one row.
SELECT A.id,
(select B.id from B where A.name = B.name) as B_ID
FROM A
Just reverse the tables and use a right join instead.
SELECT A.id,
B.id
FROM B
RIGHT JOIN A
ON A.name = B.name
I'm not familiar with java/jpa. Using pure SQL, here's one approach:
SELECT A.id AS A_id, B.id AS B_id
FROM A INNER JOIN B
ON A.name = B.name
UNION
SELECT id AS A_id, NULL AS B_id
FROM A
WHERE name NOT IN ( SELECT name FROM B );
In SQL Server, for example, You can use the *= operator to make a left join:
select A.id, B.id
from A, B
where A.name *= B.name
Other databases might have a slightly different syntax, if such an operator exists at all.
This is the old syntax, used before the join keyword was introduced. You should of course use the join keyword instead if possible. The old syntax might not even work in newer versions of the database.
I can only think of two ways that haven't been given so far. My last three ideas have already been given (boohoo) but I put them here for posterity. I DID think of them without cheating. :-p
Calculate whether B has a match, then provide an extra UNIONed row for the B set to supply the NULL when there is no match.
SELECT A.Id, A.Something, B.Id, B.Whatever, B.SomethingElse
FROM
(
SELECT
A.*,
CASE
WHEN EXISTS (SELECT * FROM B WHERE A.Id = B.Id) THEN 1
ELSE 0
END Which
FROM A
) A
INNER JOIN (
SELECT 1 Which, B.* FROM B
UNION ALL SELECT 0, B* FROM B WHERE 1 = 0
) B ON A.Which = B.Which
AND (
A.Which = 0
OR (
A.Which = 1
AND A.Id = b.Id
)
)
A slightly different take on that same query:
SELECT A.Id, B.Id
FROM
(
SELECT
A.*,
CASE
WHEN EXISTS (SELECT * FROM B WHERE A.Id = B.Id) THEN A.Id
ELSE -1 // a value that does not exist in B
END PseudoId
FROM A
) A
INNER JOIN (
SELECT B.Id PseudoId, B.Id FROM B
UNION ALL SELECT -1, NULL
) B ON A.Which = B.Which
AND A.PseudoId = B.PseudoId
Only for SQL Server specifically. I know, it's really a left join, but it doesn't SAY LEFT in there!
SELECT A.Id, B.Id
FROM
A
OUTER APPLY (
SELECT *
FROM B
WHERE A.Id = B.Id
) B
Get the inner join then UNION the outer join:
SELECT A.Id, B.Id
FROM
A
INNER JOIN B ON A.name = B.name
UNION ALL
SELECT A.Id, NULL
FROM A
WHERE NOT EXISTS (
SELECT *
FROM B
WHERE A.Id = B.Id
)
Use RIGHT JOIN. That's not a LEFT JOIN!
SELECT A.Id, B.Id
FROM
B
RIGHT JOIN A ON B.name = A.name
Just select the B value in a subquery expression (let's hope there's only one B per A). Multiple columns from B can be their own expressions (YUCKO!):
SELECT A.Id, (SELECT TOP 1 B.Id FROM B WHERE A.Id = B.Id) Bid
FROM A
Anyone using Oracle may need some FROM DUAL clauses in any SELECTs that have no FROM.
You could use subqueries, something like:
select a.id
, nvl((select b.id from b where b.name = a.name), "") as bId
from a
you can use oracle + operator for left join :-
SELECT A.id, B.id
FROM A , B
ON A.name = B.name (+)
Find link :-
Oracle "(+)" Operator
SELECT A.id, B.id
FROM A full outer join B
ON A.name = B.name
where A.name is not null
I'm not sure if you just can't use a LEFT JOIN or if you're restricted from using any JOINS at all. But as far as I understand your requirements, an INNER JOIN should work:
SELECT A.id, B.id
FROM A
INNER JOIN B ON A.name = B.name
Simulating left join using pure simple sql:
SELECT A.name
FROM A
where (select count(B.name) from B where A.id = B.id)<1;
In left join there are no lines in B referring A so 0 names in B will refer to the lines in A that dont have a match
+ or A.id = B.id in where clause to simulate the inner join