WHERE + NOT EXIST + 2 Columns - sql

I have a query, that should return all records in T1 that not linked to records in T2:
SELECT DISTINCT fldID, fldValue FROM T1
WHERE NOT EXISTS
(
SELECT T1.fldID, T1.fldValue
FROM T2
JOIN T1 ON T2.fldID = T1.fldPtr
)
But it returns empty set -- should be one record.
If I use query like this (clause on one field):
SELECT DISTINCT fldID FROM T1
WHERE fldID NOT IN
(
SELECT T1.fldID
FROM T2
JOIN T1 ON T2.fldID = T1.fldPtr
)
It returns correct result.
But the SQL Server do not support syntax
WHERE ( fldID, flrValue ) NOT IN ....
Help me please to figure out how to compose query that will check several columns?
Thanks!

You can also use EXCEPT for this:
SELECT DISTINCT fldID, fldValue FROM T1
EXCEPT
SELECT T1.fldID, T1.fldValue
FROM T2
JOIN T1 ON T2.fldID = T1.fldPtr

A more efficient and elegant query that will work with every database is:
SELECT T1.*
FROM T1
LEFT JOIN T2
ON T2.fldID = T1.fldPtr
AND T2.flrValue = T1.flrValue
WHERE T2.fldID IS NULL
The LEFT JOIN attempts to match using both criteria, then the WHERE clause filters the joins, and only non-joins have NULL values for the LEFT JOINed table.
This approach is IMHO pretty much the industry standard for finding non-matches. It is usually more efficient than a NOT EXIstS(), although several databases optimize a NOT EXISTS() to this query anyway.

Use both those columns if sub-query join:
SELECT DISTINCT fldID, fldValue FROM T1
WHERE NOT EXISTS
(
SELECT *
FROM T2
JOIN T1 ON T2.fldID = T1.fldPtr
AND T1.fldValue = T2.flrValue
)

Something like (I think, as I'm not sure I 100% understand your question):
SELECT DISTINCT fldID FROM T1
WHERE fldID NOT IN
(
SELECT T1.fldID
FROM T2
JOIN T1 ON T2.fldID = T1.fldPtr
WHERE T2.flrValue = T1.flrValue
)

If you have the same structure in both tables you can use the EXCEPT operator http://technet.microsoft.com/en-us/library/ms188055.aspx
In a more general case, you have to to use left join and find null elements in second table.

try the below Query.
select DISTINCT fldID
from Table1
WHERE cast(fldID as varchar(100))+'~'+cast(flrValue as varchar)
NOT IN (select cast(fldID as varchar(100))+'~'+cast(flrValue as varchar) from table2)

This is more easy query. It returns all T1.fldID that not linked to records in T2
SELECT DISTINCT T1.fldID
FROM T1
LEFT JOIN T2 ON T2.fldID = T1.fldPtr
WHERE T2.fldID IS NULL

Using IN to exclude a large number of values is terrible for performance. Try the following:
SELECT T1.*
FROM T1
LEFT JOIN T2 ON T2.fldID = T1.fldPtr AND T1.fldValue = T2.fldvalue
WHERE T2.fldID IS NULL

(from my comment:) you do not have to reference t1 again in the subquery. Doing so would cause a logic of the form select all the records from t1 that don't exist in t1 ..., which is always empty, just like select all blue balls that are not blue, or select all odd numbers that are even ...
The first query should be:
SELECT DISTINCT fldID, fldValue
FROM T1
WHERE NOT EXISTS (
SELECT * FROM T2
WHERE T2.fldID = T1.fldPtr
);
And: in your original query, the subquery is uncorrelated: The t1 in the subquery shadows the t1 in the main query, making the subquery not referring any table or alias from the main query: it returns either True (some row exists) or False, the result being totally uncorrelated to the rows in the main query. (yet another good reason to use aliases instead of real table names in your queries)

Related

Fectch uncommon ID between two columns

I have two tables and I need to fetch if any one ID is not present in the table 2. I tried the query but its not giving the correct result. Kindly suggest.
TABLE 1
TABLE 2
Output Should be: Because Release ID and purchase ID is not present in both the columns.
QUERY Tried :
SELECT T1_ID
FROM T1 LEFT OUTER JOIN T2
ON t1.RELEASEID=t2.RELEASEID
LEFT OUTER JOIN T2 t3
ON t1.PURCHASEID=t3.PURCHASEID
WHERE IFNULL(T2.RELEASEID,'') ='' OR IFNULL(T3.PURCHASEID,'')=''
You can use NOT EXISTS as follows:
select * from t1
where not exists (select 1 from t2
where t1.releaseid =t2.releaseid or t1.purchaseid =t2.purchaseid)
You can also use LEFT JOIN as follows:
select t1.*
from t1 left join t2
on t1.releaseid =t2.releaseid or t1.purchaseid =t2.purchaseid
where t2.t2_id is null
One method is not exists:
select t1.*
from t1
where not exists (select 1
from t2
where t2.releaseid = t1.releaseid
) and
not exists (select 1
from t2
where t2.purchaseid = t1.purchaseid
);
This should work regardless of whether ? is really a string or is supposed to represent NULL.
Note: This can take advantage of indexes on t2(releaseid) and t2(purchaseid), which can be a big boost to performance on larger data.
I think you want:
select t1.*
from table1 t1
where
(t1.release_id = '?' and t2.purchase_id = '?')
or not exists (
select 1
from table2 t2
where t1.release_id in ('?', t2.release_id)
and t1.purchase_id in ('?', t2.purchase_id)
)
If the question mark is supposed to represent null values, you can just replace all instances of = '?' with is null.
Please try this and let me know if it works.
SELECT * FROM TABLE1 WHERE NOT EXISTS (SELECT '1' FROM TABLE2 WHERE TABLE1 .RELEASEID=TABLE2.RELEASEID OR TABLE1 .PURCHASEID=TABLE2.PURCHASEID);

sql - ignore duplicates while joining

I have two tables.
Table1 is 1591 rows. Table2 is 270 rows.
I want to fetch specific column data from Table2 based on some condition between them and also exclude duplicates which are in Table2. Which I mean to join the tables but get only one value from Table2 even if the condition has occurred more than time. The result should be exactly 1591 rows.
I tried to make Left,Right, Inner joins but the data comes more than or less 1591.
Example
Table1
type,address,name
40,blabla,Adam
20,blablabla,Joe
Table2
type,currency
40,usd
40,gbp
40,omr
Joining on 'type'
Result
type,address,name,currency
40,blabla,name,usd
20,blblbla,Joe,null
try this it has to work
select *
from
Table1 h
inner join
(select type,currency,ROW_NUMBER()over (partition by type order by
currency) as rn
from
Table2
) sr on
sr.type=h.type
and rn=1
Try this. It's standard SQL, therefore, it should work on your rdbms system.
select * from Table1 AS t
LEFT OUTER JOIN Table2 AS y ON t.[type] = y.[type] and y.currency IN (SELECT MAX(currency) FROM Table2 GROUP BY [type])
If you want to control which currency is joined, consider altering Table2 by adding a new column active/non active and modifying accordingly the JOIN clause.
You can use outer apply if it's supported.
select a.type, a.address, a.name, b.currency
from Table1 a
outer apply (
select top 1 currency
from Table2
where Table2.type = a.type
) b
I typical way to do this uses a correlated subquery. This guarantees that all rows in the first table are kept. And it generates an error if more than one row is returned from the second.
So:
select t1.*,
(select t2.currency
from table2 t2
where t2.type = t1.type
fetch first 1 row only
) as currency
from table1 t1;
You don't specify what database you are using, so this uses standard syntax for returning one row. Some databases use limit or top instead.

SQL Select statement (from 2 different tables)

Heyy I'm new to sql and I'd just like to know if there's a way to retrieve select statements with conditions from other tables.
I want to select all name values that have a number that identifies that they have committed a crime. I only want to select a name once.
"SELECT distinct * FROM Table1 WHERE number LIKE table2.number "
Are you looking for IN?
SELECT t1.*
FROM Table1 t1
WHERE t1.number IN (SELECT t2.number FROM table2 t2 t2.number);
Under most circumstances, the rows in a table should be unique. So, you don't need SELECT DISTINCT. The DISTINCT can add a considerable amount of overhead to such a query.
You can able to use INNER JOIN like below,
select tbl1.Name from tableOne tbl1
inner join tableTwo tbl2 ON tbl1.commonKey = tbl2.commonKey
where tbl1.columnName = 'any value'

How to join select with itself in postgresql?

How to join select with itself in postgresql?
SELECT *
FROM (
SELECT src, dst FROM records
) as t1
JOIN t1 t2
USING(src)
UPDATE:
my table doesn't exists already and I create a table with "SELECT" and I want join this selected table with itself.
Use a Common Table Expressiom:
with t1 as
(
SELECT src, dst FROM records
)
SELECT *
FROM t1 JOIN t1 t2
USING(src)
You should fix the question. But one obvious problem is that you cannot re-use a table alias to define another table in the same from clause where it is defined. Hence, I think you want:
SELECT r1.src, r1.dst, r2.src, r2.dst
FROM records r1 JOIN
records r2
USING (src);

Unable to understand query

I am working on an SSIS job that contains a complex query.
It has some thing like :
some sql statements
left outer join
(
select query joining two more tables )
table1
here, i am unable to understand what that table1 mean ? Is it a kind of temporary view
created . This table1 is used in the other parts of query . But, actually the table1 does
exists in the database.
Is it like , the results of the select query in the parenthesis is created as table1
Please clarify me on this..
I am not able to put down my code because of Security Policies
Here is SQL Fiddel example
Below is the sample query
Select Temp1.id,Table1.id Table1_id
from Temp1
left Outer join
(
Select Temp2.id
from Temp2
join Temp3
On Temp2.id = Temp3.id
) Table1
on Temp1.id = Table1.Id
In above example table1 is the Alias for data coming from joinsof two tables (temp2 and temp3)
table1 is an alisas your subquery. It's the name of subquery you can use with columns for example table1.col1
It is an alias for the query in the parenthesis.
If you would remove that you would get an error.
Aliases are also good when you have the same column in more than on joined tables, so you can distinquish them.
For instance if colX is both in Table1 and Table2 you would have a query like:
SELECT T1.colX,T2.colX
FROM Table1 T1
JOIN Table2 T2
ON T1.id = T2.id