SQL select result from two fields where equal to same search result - sql

Currently SQL statement as below:
SELECT result FROM tableA WHERE
field1 = (SELECT x FROM tableB WHERE field3 = "XXX") OR
field2 = (SELECT x FROM tableB WHERE field3 = "XXX");
Can simplify the two select statementSELECT x FROM tableB WHERE field3 = "XXX" ?
Have using JOIN and currently the statement as below:
SELECT resultB from tableA a join
tableB b on
b.field4 = a.field1 or
b.field4 = a.field2 where
b.field3 = "XXX";
Further on, "XXX" is from below SQL statement:
SELECT DISTINCT(resultA) FROM tableC c WHERE c.field5 is false;
How to combine this to having result as below:
resultA(1), resultB(1)
resultA(2), resultB(2)
resultA(3), resultB(3)
...
Thanks.

You can join the tables.
SELECT
a.result
FROM tableA a
join tableB b on b.x = a.field1 or b.x = a.field2
where b.field3 = 'XXX'
https://www.w3schools.com/sql/sql_join.asp

You can do it with EXISTS:
SELECT a.result
FROM tableA a
WHERE EXISTS (
SELECT 1
FROM tableB b
WHERE b.field3 = 'XXX' AND b.x IN (a.field1, a.field2)
)

Although you can "simplify" the logic, if you care about performance that is probably not a good route. Instead, I would suggest using exists twice:
SELECT a.result
FROM tableA a
WHERE EXISTS (SELECT 1
FROM tableB b
WHERE b.x = a.field1 AND b.field3 = 'XXX'
) OR
EXISTS (SELECT 1
FROM tableB b
WHERE b.x = a.field2 AND b.field3 = 'XXX'
);
This can make use of an index on tableB(x, field3).

Related

SQL query to select from one table based on a column value in other table

I have two tables and I want to select all values from "TABLE A" that have a different value in a column from "TABLE B".
I tried this
SELECT A.* FROM tableA A
left join tableB B ON A.id = B.id WHERE B.column <> 1;
But this just return the value that I want to ignore.
SELECT A.*
FROM tableA A
INNER JOIN tableB B
ON A.id = B.id
WHERE B.column != 1;
or
SELECT A.* FROM tableA A WHERE A.Id NOT IN (SELECT B.Id FROM tableB B WHERE B.column != 1)
Depends on your SQL you can use <> or !=
I would suggest not exists:
SELECT A.*
FROM tableA A
WHERE NOT EXISTS (SELECT 1 FROM tableB B WHERE A.id = B.id AND B.column = 1);
Using a JOIN can result in duplicated rows, if more than one row in B matches the JOIN condition.

Converting a PostgreSQL query with IN / NOT IN to JOINs

I currently have two tables with the same structure. Table A (as an example) has 10,000 rows, table B has 100,000 rows. I need to obtain the rows that are in Table B that are not in Table A, but only if certain fields are the same (and one is not).
Right now, the query is something like:
select *
from tableA A
where (A.field1, A.field2) in (select field1, field2 from tableB B)
and A.field3 not in (select field3 from B)
This works, but probably a better performant solution could be done with JOINs. I have tried to do it but all I get is a very huge list of duplicated rows. Could someone point me in the right direction?
Based on your current query this is what it translates to as joins:
select *
from tableA A
inner join tableB B on A.field1 = B.field1 and A.field2 = B.field2
left outer join tableB C on A.field3 = C.field3
where c.field3 is null
A faster query would be:
select A.pk
from tableA A
inner join tableB B on A.field1 = B.field1 and A.field2 = B.field2
left outer join tableB C on A.field3 = C.field3
where c.field3 is null
group by A.pk
This would give you the rows you need to add to tableB because they aren't found.
Or you can just get the fields you want to pull over:
select A.field1, A.field2, A.field3
from tableA A
inner join tableB B on A.field1 = B.field1 and A.field2 = B.field2
left outer join tableB C on A.field3 = C.field3
where c.field3 is null
group by A.field1, A.field2, A.field3
[NOT] EXISTS is your friend:
SELECT *
FROM tableA A
WHERE EXISTS ( SELECT * FROM tableB B
WHERE A.field1 = B.field1
AND A.field2 = B.field2
)
AND NOT EXISTS ( SELECT * FROM tableB B
WHERE A.field3 = B.field3
);
Note: if the joined columns are NOT NULLable, the [NOT] EXISTS() version will behave exactly the same as the [NOT] IN version
Reading the question text again (and again):
I need to obtain the rows that are in Table B that are not in Table A, but only if certain fields are the same (and one is not).
SELECT *
FROM tableB B
WHERE EXISTS ( SELECT * FROM tableA A
WHERE A.field1 = B.field1
AND A.field2 = B.field2
AND A.field3 <> B.field3
);

If select returns nothing then

I'm trying to write select as:
SELECT * FROM table1 a
WHERE a.d > (
SELECT b.d FROM table2 b
WHERE a.id = b.id and a.Something = 1
)
BUT if the nested select does not returns any value so SELECT does not returns anything either.
Is possible to write something like:
SELECT * FROM table1 a WHERE a.d >
(SELECT * FROM
IF EXISTS (
SELECT b.d FROM table2 b WHERE a.id = b.id and a.Something = 1
)
SELECT b.d FROM table2 b WHERE a.id = b.id and a.Something = 1 )
ELSE
SELECT '0'
)
You can use COALESCE
SELECT *
FROM table1 a
WHERE a.d > COALESCE((SELECT b.d FROM table2 b WHERE a.id = b.id and a.Something = 1), '0')
COALESCE
Evaluates the arguments in order and returns the current
value of the first expression that initially does not evaluate to
NULL.
See this link for more info.

How to LEFT JOIN in DB2 iseries with first row?

I have need a query that JOIN a TABLE with A first row of other table value based:
SELECT * FROM TABLEA A LEFT JOIN
(SELECT * from TABLEB
WHERE FIELD1 <> '3' and FIELD2 = 'D' AND A.CODE=CODE
FETCH FIRST 1 ROW ONLY
) B
on a.FIELDA = b.FIELDA
and A.FIELDB = B.FIELDB
but DB2 return ERROR because can't use A.CODE
How can solve this?
You need to use the nested table expression:
SELECT * FROM TABLEA A LEFT JOIN
LATERAL (SELECT * from TABLEB
WHERE FIELD1 <> '3' and FIELD2 = 'D' AND A.CODE=CODE
FETCH FIRST 1 ROW ONLY
) B
on a.FIELDA = b.FIELDA
and A.FIELDB = B.FIELDB
This is a highly optimized statement.
Your not getting any data from tableb and your going for first row so you just need exists clause.
select a.* from tablea a
where exists (select * from tableb b
where a.fielda = b.fielda
and a.fieldb = b.fieldb
and b.code = a.code
and b.field2 = 'd' and b.field1 <> '3')
You can use the OLAP function row_number() to rank the records according to somefield(s) within a (fielda,fieldb,code) group. Somefield might be a transaction id, or sequence, for example. The order by clause is optional there, but without it, you might be randomly picking which record is the first in the group.
WITH B AS
(SELECT *,
row_number() over (partition by fielda,fieldb,code
order by somefield
) as pick
from TABLEB
WHERE FIELD1 <> '3'
and FIELD2 = 'D'
)
SELECT *
FROM TABLEA A LEFT JOIN B
on a.FIELDA = b.FIELDA
and A.FIELDB = B.FIELDB
and A.CODE = B.CODE
where pick=1

update table with join without PK in oracle

UPDATE
(
SELECT
a.COL1
FROM
TABLE1 a,
TABLE2 b,
TABLE3 c
WHERE
a.name = b.name
c.ccol = b.ccol AND
AND b.col1 = 'anyvalue'
AND a.col2 = 'anothervalue'
) u
SET
u.COL1 = 'VALUE'
This query does not work, since TABLE1 does not contains PK. How to write such a query ?
The following should achieve what it looks like you are trying to achieve above:
UPDATE TABLE1
SET COL1 = 'VALUE'
WHERE EXISTS
( SELECT 1
FROM TABLE2 B
INNER JOIN TABLE3 C
ON B.Ccol = C.Ccol
WHERE b.Name = Table1.Name
AND b.Col1 = 'AnyValue'
AND c.Col1 = 'AnotherValue'
)
I've never worked in oracle, but try something like this. Not having a pk shouldn't be an issue, as long as your joins & where statements are correct.
This is the SQL equivalent of what you're asking for
UPDATE u
SET u.COL1 = 'VALUE'
FROM Table1 AS u
INNER JOIN Table2 AS b ON u.name = b.name
INNER JOIN Table3 AS c ON c.ccol = b.ccol
WHERE b.col1 = 'anyvalue' AND u.col2 = 'anothervalue'