Oracle to SQL Server conversion error - sql

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')

Related

How to update PostgreSQL db with a triple join?

I have three tables (a,b,c). I want to update a column in table a (named email) where
a.id = b.id, b.name = c.name.
This is what I have so far.
UPDATE a
SET email = "hi#gmail.com"
FROM a INNER JOIN b ON a.id = b.id
INNER JOIN c ON b.name = c.name
WHERE email IS NULL;
However I'm getting the error that table name a is specified more than once.
What can I do?
You don't specify the table being updated in the from clause. Use the where clause to correlated it:
UPDATE a
SET email = 'hi#gmail.com'
FROM b JOIN
c
ON b.name = c.name
WHERE a.id = b.id AND a.email IS NULL;

SQL JOIN with OPENQUERY

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

SQL Select ISNULL not working

I used the query below to extract the data fro the table but it does not working.
SELECT A.ID, AVG(ISNULL(score,0)) AS sc FROM A
LEFT OUTER JOIN B ON A.ID = B.ID
WHERE A.aClass = '1st'
I wanted it to return all the data from Table A with its corresponding average score and return 0 if there is no score yet. Can anyone help me figure out the problem.
Try this
SELECT A.ID, AVG(ISNULL(B.score,0)) AS sc
FROM A
LEFT OUTER JOIN B ON A.ID = B.ID
WHERE A.aClass = '1st'
GROUP BY A.ID

How to use oracle outer join with a filter where clause

If i write a sql:
select *
from a,b
where a.id=b.id(+)
and b.val="test"
and i want all records from a where corresponding record in b does not exist or it exists with val="test", is this the correct query?
You're much better off using the ANSI syntax
SELECT *
FROM a
LEFT OUTER JOIN b ON( a.id = b.id and
b.val = 'test' )
You can do the same thing using Oracle's syntax as well but it gets a bit hinkey
SELECT *
FROM a,
b
WHERE a.id = b.id(+)
AND b.val(+) = 'test'
Note that in both cases, I'm ignoring the c table since you don't specify a join condition. And I'm assuming that you don't really want to join A to B and then generate a Cartesian product with C.
Move the condition into the JOIN clause and use the ANSI standard join pattern.
SELECT NameYourFields,...
FROM A
LEFT OUTER JOIN B
ON A.ID = B.ID
AND B.VAL = 'test'
INNER JOIN C
ON ...
A LEFT OUTER JOIN is one of the JOIN operations that allow you to specify a join clause. It preserves the unmatched rows from the first (left) table, joining them with a NULL row in the shape of the second (right) table.
So you can do as follows :
SELECT
FROM a LEFT OUTER JOIN b
ON a.id = b.id
--Note that you have used double quote "test" which is not used for varchar in SQL you should use single quote 'test'
AND b.val = 'test';
SELECT * FROM abc a, xyz b
WHERE a.id = b.id
AND b.val = 'test'

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