Oracle Query with AND and OR - sql

How can I write the following scenario as query in Oracle
SELECT *
FROM table1
WHERE col1 = 'SOMENAME' WITH (EITHER COL2 = 'Y' OR COL3 = 'Y')

You need to use AND:
Select *
from table1
where col1 = 'SOMENAME'
AND (COL2 = 'Y' OR COL3 = 'Y')

Related

SQL: How to compare two rows from same table where second row is given by first's values

Below is my SQL Server query which works great, but as you can see I am fetching the same row multiple times. Is there a way to optimise this by doing a SELECT only once? Thanks.
SELECT TOP 1 1
FROM some_table
WHERE col1 = #col1
AND (col2 IN ('N', 'C', 'U') OR
col3 != (SELECT t.col3 FROM some_table t
WHERE t.id = id AND t.revision_id = revision_id - 1) OR
col4 != (SELECT t.col4 FROM some_table t
WHERE t.id = id AND t.revision_id = revision_id - 1) OR
col5 != (SELECT t.col5 FROM some_table t
WHERE t.id = id AND t.revision_id = revision_id - 1) OR
col6 != (SELECT t.col6 FROM some_table t
WHERE t.id = id AND t.revision_id = revision_id - 1)
)
Note: I only need to see only if one such column exists (see SELECT 1 1), which is more than likely to give be 1 most times. So I do NOT want to do a join of the table which has millions of rows.
First, you have an error with the column names in the subqueries. See Qualifying column names in subqueries
column names in a statement are implicitly qualified by the table referenced in the FROM clause at the same level.
So, all of these columns belong to t: t.id=id AND t.revision_id=revision_id-1
And the query:
SELECT TOP 1 1
FROM some_table s
WHERE col1=#col1
AND
(
col2 IN ('N','C','U') OR
EXISTS(SELECT * FROM some_table where id = s.id
AND revision_id = s.revision_id - 1 AND
(col3 != s.col3 OR col4 != s.col4 OR col5 != s.col5 OR col6 != s.col6)
)
)
You can use apply here to select multiple columns form a related row.
This is just an approximation of what you need as you haven't supplied any example data and expected results. You may need to use a top (1) with an appropriate order by clause or aggregate if the apply can return more than one row:
select *
from some_table t
outer apply (
select col3, col4, col5, col6
from some_table t2
where t2.id = t.id AND t2.revision_id = t.revision_id-1
)t2
where col1 = #col1
and (
col2 IN ('N','C','U') or
t.col3 != t2.col3 or
t.col4 != t2.col4 or
t.col5 != t2.col5 or
t.col6 != t2.col6
);

Pyspark sql for oracle subquery

How to write following oracle based sql query into equivalent pyspark sql as this is not supported as it is due to nesting under spark.sql(*query)
Is there any way to write this using pyspark dataframe too ?
SELECT TABLE1.COL1
FROM TABLE1
WHERE COL2 = (
SELECT MAX(COL2)
FROM TABLE1
WHERE TABLE1.COL3 = TABLE2.COL3 OR TABLE1.COL4 = TABLE2.COL4
)
TABLE1 has columns COL1, COL2, COL3, COL4
TABLE2 has columns COL3, COL4
Can you use this syntax, if you use a JDBC driver :
sql_request = "(select TABLE1.COL1 FROM TABLE1 WHERE COL2 = (SELECT MAX(COL2) FROM TABLE1 WHERE TABLE1.COL3 = TABLE2.COL3 OR TABLE1.COL4 = TABLE2.COL4))"
df_request = spark.read.jdbc(url=url,table=sql_request,properties=db_properties)
Hope this can help
You can try this one.
from pyspark.sql.functions import max
table1.select(table1.COL1)\
.where(table1.COL2 == table2.select(max(table2.COL2).alias('MAX_COL2'))\
.where((table1.COL3 == table2.COL3) | (table1.COL4 == table2.COL4)).collect().head().MAX_COL2).show()
Hope this can help.

SQL: Ignore Condition in WHERE clause

I am confused on how to exclude one of the conditions in WHERE clause if it evaluates to NULL
SELECT TB1.COL3
FROM TB1, TB2
WHERE TB1.COL1 = TB2.Col1
AND TB2.COL1 = '12345'
AND (TB2.COL3 = (SELECT MIN(TB3.COL4)
FROM TB3
WHERE COL1 = TB2.COL1
AND COL2 in ('A', 'B')
AND COL4 IN (SELECT COL3 FROM TB4
WHERE COL1 = TB4.COL1)))
AND ROWNUM = 1;
How can I modify the above query to ignore the "AND condition TB2.COL3" if the following condition SELECT MIN(TB3.COL4) FROM TB3 evaluates to some value except NULL. If NULL the above query should be executed as below:
SELECT TB1.COL3
FROM TB1, TB2
WHERE TB1.COL1 = TB2.Col1
AND TB2.COL1 = '12345'
AND ROWNUM = 1;
I think you could pull this off with a coalesce:
SELECT TB1.COL3
FROM TB1, TB2
WHERE TB1.COL1 = TB2.Col1
AND TB2.COL1 = '12345'
AND (TB2.COL3 = COALESCE((SELECT MIN(TB3.COL4)
FROM TB3
WHERE COL1 = TB2.COL1
AND COL2 in ('A', 'B')
AND COL4 IN (SELECT COL3 FROM TB2
WHERE COL1 = TB2.COL1)), TB2.COL3))
AND ROWNUM = 1;
Here we are just wrapping that SELECT statement in COALESCE which, if it returns null, will grab the second parameter's value instead, which is the same column we are comparing. Since TB2.COL3 = TB2.COL3 is obviously TRUE then this filter will not have any impact on the result set.
Also, it's generally recommended that you stop using comma's in your FROM clause and use proper JOIN syntax. It's been around for over 2 decades now:
SELECT
TB1.COL3
FROM
TB1
INNER JOIN TB2
ON TB1.COL1 = TB2.Col1
WHERE
TB2.COL1 = '12345'
AND
(
TB2.COL3 = COALESCE
(
(
SELECT
MIN(TB3.COL4)
FROM
TB3
WHERE
COL1 = TB2.COL1
AND COL2 in ('A', 'B')
AND COL4 IN
(
SELECT
COL3
FROM
TB2
WHERE
COL1 = TB2.COL1
)
),
TB2.COL3
)
)
AND ROWNUM = 1;

Python pydobc SQL ODBC Microsoft Access Drive Too few parameters

Trying to obtain filtered results matching TableA and a TableB with both a column col1 and WHERE a python variable "Bingo" NOT IN TableB col3
bingo = 'Data1'
SQL = 'SELECT a.* FROM TABLEA a WHERE a.col1 NOT IN (SELECT col1 FROM TABLEB) AND (?) NOT IN (SELECT col3 FROM TABLEB);'
rows = cur.execute(SQL,bingo).fetchall()
You cannot parameterize the name of the field. You are better off using Python's substitutions/formatting with str.format() such as this:
bingo = 'Data1'
SQL = 'SELECT a.* FROM TABLEA a WHERE a.col1 NOT IN (SELECT col1 FROM TABLEB) AND {} NOT IN (SELECT col3 FROM TABLEB);'.format(bingo)
rows = cur.execute(SQL).fetchall()

Oracle SQL : Updating a column with SUM query of another table

I have two tables :
Table1 with 5 columns (col1, col2, col3, col4, val1) and Table2 with Table1 with 5 columns (col1, col2, col3, col4, val2).
1. The Table1.val1 doesn't contain any value.
2. For both Table1 and Table2, col1, col2, col3 and col4 are the same and they are the primary key.
What I would like to do, is to update the Table1.val1 with the sum(Table2.val2) when Table1.col1 = Table2.col1 and Table1.col2 = Table2.col2 and Table1.col3 = Table2.col3 and Table1.col4 = Table2.col4.
I did something like :
UPDATE Table1
SET val1 = (
select t_sommevbrute.sumvalbrute from (
Select col1,col2,col3,col4,SUM(val2) sumvalbrute
From Table2
Where col3 = 2014 And col2=51
GROUP BY col1, col2, col3, col4) t_sommevbrute
WHERE Table1.col1 = t_sommevbrute.col1
and Table1.col2 = t_sommevbrute.col2
and Table1.col3 = t_sommevbrute.col3
and Table1.col4 = t_sommevbrute.col4)
But related to this question: Oracle SQL: Update a table with data from another table , I should have WHERE EXISTS clause.
Any help please!!
Thanks.
You can do this in following way:-
With Use of Temp Table:-
First Create Temp Table:-
Create table temp1 as
Select col1,col2,col3,col4,SUM(val2) as sumvalbrute
From table2
Where col3 = 3 And col2=2
GROUP BY col1, col2, col3, col4;
And then use Temp table to update Main Table1:-
UPDATE table1 SET table1.val1 = (SELECT temp1.sumvalbrute
FROM temp1
WHERE Table1.col1 = temp1.Col1
AND Table1.col2 = temp1.Col2
AND Table1.col3 = temp1.Col3
AND Table1.col4 = temp1.Col4);
SQL Fiddle :- http://sqlfiddle.com/#!4/4864d/5
WithOt Use of Temp Table:-
UPDATE table1 SET table1.val1 = (SELECT temp1.sumvalbrute
FROM
(Select col1,col2,col3,col4,SUM(val2) as sumvalbrute
From table2
Where col3 = 3 And col2=2
GROUP BY col1, col2, col3, col4) temp1
WHERE Table1.col1 = temp1.Col1
AND Table1.col2 = temp1.Col2
AND Table1.col3 = temp1.Col3
AND Table1.col4 = temp1.Col4);
SQL Fiddle:- http://sqlfiddle.com/#!4/c9286/2
You can simplify your query greatly:
UPDATE Table1
SET val1 = (select SUM(val2)
from Table2 t
where Table1.col1 = t.col1 and
Table1.col2 = t.col2 and
Table1.col3 = t.col3 and
Table1.col4 = t.col4
)
Where col3 = 2014 And col2 = 51;
You could use where exists. The purpose is to prevent NULL values when there is no match. However, I think pulling the where clause outside probably solves this problem. I note that the where clause is using the same values as the correlation conditions.
You can try this:
UPDATE t1 SET t1.val1 = SUM(t2.val2)
FROM table1
INNER JOIN table2 t2 ON t2.col1 = t1.col1
and t2.col2 = t1.col2
and t2.col3 = t1.col3
and t2.col4 = t2.col4
This kind of update can be achieved ALSO using MERGE statement:
Merge into Table1 using ( select SUM(val2) as val2, t.col1, t.col2, t.col3, t.col4
from Table2 t
group by t.col1, t.col2, t.col3, t.col4
) t -- This is the alias for table 2
on ( Table1.col1 = t.col1
and Table1.col2 = t.col2
and Table1.col3 = t.col3
and Table1.col4 = t.col4
)
when matched then
UPDATE Table1.val1 = t.val2 --HERE IS YOUR **UPDATE**
where Table1.col3 = 2004
and Table1.col2 = 51
;
commit;
Please don't forget to ADD ALIASES to the tables, and a good COMMIT after this code
This solution avoid you from create temporary tables, and works pretty well
Best regards.