EXCEPT keyword in Oracle - sql

I'm trying to use the EXCEPT keyword in Oracle 10.1.0.2.0, but kept getting error 'Unknown Command'. I've tried googling around and someone said the keyword is MINUS, so I used MINUS, instead, but I still got the same error.
Any idea?
Thanks.
So here's my query.
I'm finding the name of students who enrolls in ALL courses with course number > 500
SELECT s.name
FROM Students s
WHERE NOT EXISTS
(
SELECT c.id
FROM Courses c
WHERE c.number > 500
MINUS
SELECT e.course_id
FROM Enrollment e
WHERE e.student_id = s.id
);

Oracle MINUS is an operator; it's equivalent to EXCEPT in SQL Server. Here is a previous post explaining the difference. Here's a trivial example:
SELECT a, b, c
FROM table_a
MINUS
SELECT a, b, c
FROM table_b
If you still have problems, add the complete query you are using to your question; it's likely a simple syntax error.

Oracle 20c will support EXCEPT/EXCEPT ALL keywords.
SELECT col1, col2
FROM t1
EXCEPT
SELECT col1, col2
FROM t2;
or EXCEPT ALL if you want to handle duplicates:
SELECT col1, col2
FROM t1
EXCEPT ALL
SELECT col1, col2
FROM t2;
4.6 Set Operators
Set operators combine the results of two component queries into a single result.
EXCEPT All distinct rows selected by the first query but not the second
EXCEPT ALL All rows selected by the first query but not the second including duplicates

Related

Combining two different result set into a single query

Two different queries, produce two different result set.
Query 1:
Select a.customer_name, b.salary, c.manager_name
from
table123 a
left join table456 b on a.id=b.id
left join table789 c on a.id=c.id
Query2:
Select d.prty_id, e.party_val, f.prty_nme
from
table111 d
Left join table222 e on d.id=e.id
Left join table333 f on d.id=f.id
Now I have to write one single query, which will merge this above two query's result set and display one single result set.
Can anyone please help me on this.
Output value I need to insert in a new table whose column will be like below:
customer_name salary manager_name prty_id party_val prty_nme
According to your expected result, you can use UNION or UNION ALL.
The Oracle UNION operator is used to combine the result sets of 2 or more Oracle SELECT statements. It removes duplicate rows between the various SELECT statements.
The Oracle UNION ALL operator is used to combine the result sets of 2 or more SELECT statements. It returns all rows from the query and it does not remove duplicate rows between the various SELECT statements.
Select con1,... , coln
from tab1
where...
union
Select con1,... , coln
from tab2
where...
Just make sure your data types match up.

SQL DISTINCT in the middle of select

Does the distinct need to always be the first line after the select? Every time I try the following, I get a syntax error near the keyword 'DISTINCT, if not, how can I make the distinct work without begin the after the select.
SELECT COLUMN1,
DISTINCT COLUMN 2,
COLUMNM 3
FROM TABLE_1
it works if I have the distinct at in the first line like this:
SELECT DISTINCT COLUMN2,
COLUMN1,
COLUMN3
FROM TABLE_1
The DISTINCT clause filters out FULL DUPLICATE ROWS. It goes right after the SELECT keyword, since it applies to the entire row, not single columns. You cannot use it in between columns.
Maybe I know where does this confusion comes from. While DISTINCT is indeed an optional SELECT predicate, which acts on each output row as a whole it can also be used inside function argument (which is also a statement on its own), e.g.:
SELECT s.id, s.name, GROUP_CONCAT(DISTINCT p.name SEPARATOR "; "), ...
FROM subjects AS s
LEFT JOIN property AS p ON p.subject_id = s.id
LEFT JOIN property2 AS p2 ON p2.subject_id = s.id
...
GROUP BY s.id;
The purpose of DISTINCT here is self-explanatory. But again, if we look at this inner statement DISTINCT comes first.
Another example of same kind would be COUNT(DISTINCT column).

Select Table A minus Table B where condition consists of two columns

I have two tables. Table A and table B.
I would like to select everything from table A which is NOT in table B.
Sounds easy the catch is I need to select it based on two values (two columns)
revision AND casetype. Something like this.
select a.revision, a.casetype from A a
minus
select b.revision, b.casetype from B b;
The problem is I won't get back ID from table A.
Is it possible to select whole table A minus table B where conditions consist of two columns ? I would like to stick to SQL (no PL/SQL)
I also tried to write something like query below but I guess I can't do it since I need to check revision AND casetype altogether
select * from A a where a.casetype IN (select...) and a.revision IN (select...)
Any idea how to work around ? Thanks
Sure, I believe a basic not exists check should work.
select a.id, a.revision, a.casetype
from A a
where not exists (
select 1
from B
where revision = a.revision and casetype = a.casetype
);
Oracle supports tuples, so if you wanted you could do:
select a.*
from a
where (a.revision, a.casetype) in (select a.revision, a.casetype from A a
minus
select b.revision, b.casetype from B b
);
I would normally go for not exists, but this is the solution that builds on what you have already done.
except should work
select a.revision, a.casetype from A a
except
select b.revision, b.casetype from B b;

SQLite Count() and Group By not getting the count of rows

I've written my SQLite query a couple different ways: 1 with a Group By and Count(), the other with a nested select that does a count().
Here's the current version:
Select t.A,
t.B,
(Select Count(*) As CurrentCount From tableB b Where b.B = t.B) As CurrentCount
From tableA t
Why does this not work in SQLite, but it's working just fine (both versions actually, the other using a group by) in SQL Server/T-SQL? Is it because of the join in the sub/nested select?
Edit: Let me clarify, I'm getting 0 for a count every time...
Edit2: I tried taking out the where clause in my nested select and it still returns 0 even though I know the table has records (133 to be exact)
Edit (Final Solution): This was NOT a code issue, it was a data issue. It's nothing that anyone would have caught. My "refresh" script that was reading the records from SQL Server was reading all 133, but the actual insert into my SQLite database had a missing comma, therefore the table WAS empty, hence the 0 records. Sorry for wasting everyone's time.
Something like
Select t.A
,t.B
,b.CurrentCount
From tableA t
INNER JOIN (Select B, Count(*) [CurrentCount] From tableB b GROUP BY B) as B
ON b.B = t.B

Column does not exist in the IN clause, but SQL runs

I have a query that uses the IN clause. Here's a simplified version:
SELECT *
FROM table A
JOIN table B
ON A.ID = B.ID
WHERE B.AnotherColumn IN (SELECT Column FROM tableC WHERE ID = 1)
tableC doesn't have a Column column, but the query executes just fine with no error message. Can anyone explain why?
This will work if a table in the outer query has a column of that name. This is because column names from the outer query are available to the subquery, and you could be deliberately meaning to select an outer query column in your subquery SELECT list.
For example:
CREATE TABLE #test_main (colA integer)
CREATE TABLE #test_sub (colB integer)
-- Works, because colA is available to the sub-query from the outer query. However,
-- it's probably not what you intended to do:
SELECT * FROM #test_main WHERE colA IN (SELECT colA FROM #test_sub)
-- Doesn't work, because colC is nowhere in either query
SELECT * FROM #test_main WHERE colA IN (SELECT colC FROM #test_sub)
As Damien observes, the safest way to protect yourself from this none-too-obvious "gotcha" is to get into the habit of qualifying your column names in the subquery:
-- Doesn't work, because colA is not in table #test_sub, so at least you get
-- notified that what you were trying to do doesn't make sense.
SELECT * FROM #test_main WHERE colA IN (SELECT #test_sub.colA FROM #test_sub)
If you want to avoid this situation in the future (that Matt Gibson has explained), it's worth getting into the habit of always using aliases to specify columns. E.g.:
SELECT *
FROM table A
JOIN table B
ON A.ID = B.ID
WHERE B.AnotherColumn IN (SELECT C.Column FROM tableC C WHERE C.ID = 1)
This would have given you a nice error message (note I also specified the alias in the where clause - if there wasn't an ID column in tableC, you'd have also had additional problems)