Is it possible to rewrite a NOT IN query to use indexes? - sql

Sqlite does not support the use of indexes in queries based around a NOT IN clause.
Is it possible to logically rewrite a query like the following in such a way that it will only use the operators listed at the link above?
The query:
Select *
From table
Where table-column not in (
Select table-column
From table2);
The operators listed as being able to use an index:
column = expression
column > expression
column >= expression
column < expression
column <= expression
expression = column
expression > column
expression >= column
expression < column
expression <= column
column IN (expression-list)
column IN
(subquery)
column IS NULL

Use a LEFT JOIN as described in section 6.
SQLFiddle with sample data here. Expand View Execution Plan to confirm that the original query does a table scan, while the LEFT JOIN query uses the index.

Select A.*
From table a
left join table2 b
on a.table-column = b.table-column
WHERE b.table-column is null

SELECT
*
FROM
Table1
LEFT JOIN Table2
ON Table1.table-column = Table2.table_column
WHERE
Table2.table_column IS NULL

Related

How do I use a WHERE on a calculated column

I have a calculated column in my sql query and I want to use it in my where clause, normally I use the table names and then what I want to filter. In this case I don't have that option
this is in my SELECT statement, Its a basic margin calculation SELL-COST/SELL*100 to give me the margin.
CONVERT(DECIMAL(10,2),(T_CUSTOMERPRICELISTBASESTANDARDRULE_PRICEDEFINITION.C_NETPRICE - T_PRODUCT_PURCHASING.C_LISTPRICEACTUAL)/T_CUSTOMERPRICELISTBASESTANDARDRULE_PRICEDEFINITION.C_NETPRICE ) * 100 Percentage
what I would like to do is use the WHERE clause to filter the above statement anything below 15
You need to use a table expression to name that column officially. Then the outer query can use it as needed. For example:
select *
from (
select a, b, a + b as c from t
) x
where c > 10 -- "c" exists in the outer query

Comparing two fields' values in Oracle SQL

I have this statement in Oracle:
select agnt_name,
exporter_name
from
(
select agnt_name,
exporter_name
from Exporters
union all
select agnt_name,
exporter_name
from agents
)
now if I add this condition:
WHERE agnt_name = exporter_name
My question is: Will the query compare the values in both fields & if they equal it'll show the records?
Or will this condition be like a join condition?
You have no join in your query -- not even an implicit join. Hence, adding the condition will just compare the values in the two columns in the same row.

In sql server why cant we use functions when comparing data from two tables [duplicate]

This question already has answers here:
Sql Server : How to use an aggregate function like MAX in a WHERE clause
(6 answers)
Closed 7 years ago.
can someone please tell me what is wrong with the following query
select 1
from table1 a,
table2 b
where a.pdate=max(b.pdate)
It is not compiled.
the other way to write this query is
set #pdate=pdate from table2
select 1
from table1 a,
table2 b
where a.pdate=max(b.pdate)
But I want to understand what is wrong with the first query.
Thanks
But I want to understand what is wrong with the first query.
The error message tells you something that could be of value to you.
An aggregate may not appear in the WHERE clause unless it is in a
subquery contained in a HAVING clause or a select list, and the column
being aggregated is an outer reference.
The max() function is an aggregate that returns the max value for a set of rows. The where clause is used to filter rows. So if you use an aggregate in the place where you are doing the filtering it is not clear what rows you actually want the max value for.
A rewrite could look like this:
select 1
from dbo.table1 as a
where a.pdate = (
select max(b.pdate)
from dbo.table2 as b
);
even second query is wrong.
Correct way,
Select #pdate=max(pdate) from table2
select 1
from table1 a where a.pdate=#pdate
or,
select 1
from table1 a where a.pdate=(Select max(pdate) from table2)
if you mention another column name apart from aggregate column then you hv to use group by

How to select two columns with a single WHERE clause?

How can I select more than one table in sql server while using a single where clause condition
for both tables? For example, if I had two tables named table1, table2, then:
select * from table1,table2 where rollno=1
But in the above query it gives me error -
ambiguous column
which is logical.
Give Alias name or use the tablename to avoid ambiguous column error and try.
select * from table1 A,table2 B where A.rollno=1 AND B.rollno=1

Oracle Having > Single Row

I have an Oracle query, which has something to the effect of
Having Count(field) > (Long SQL statement that returns one row)
Both sides of the query work alone, but together I get a "not a group by" expression.
When replacing the long SQL statement with a number it works, but I assumed the two were equivalent if only one row is returned?
Edit
After doing some playing around I realized:
... Table T ... Having Count(field) > (Long SQL statement with Table A Where A.field = T.field)
It works when I replace T.field with any of the specific options for T.field, but when I reference T.field specifically I get the same "not a group by expression"
When Oracle parses your query it doesn't know if the query is going to return only one row or a bunch of rows. So simply append group by your_column to the end of your query.
For example this query returns one row:
select count(*) from user_objects;
But if I wanted to include sysdate along with that, I would have to do
select
sysdate the_date,
count(*)
from
user_objects
group by
the_date;
SELECT ...
FROM Table T ...
GROUP BY T.afield
HAVING Count(T.anotherfield)
> (Long SQL statement with Table A Where A.somefield = T.afield)
should work ok.
SELECT ...
FROM Table T ...
GROUP BY T.anotherfield
HAVING Count(T.anotherfield)
> (Long SQL statement with Table A WHERE A.somefield = T.afield)
should not work. A field (like T.afield) that is not included in the GROUP BY list, cannot be referenced in SELECT, HAVING or ORDER BY clauses. Only aggregate functions of that field can be referenced - you could have WHERE A.somefield = MIN(T.afield) for example.