SQL DISTINCT in the middle of select - sql

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).

Related

SQL with SubSelect refering to same Table as Inital load is slow

i DISTINCT load multiple Tables together:
Simple DISTINCT SELECT Table1.Val1, Table2.Val2, Table1.Val3,...
FROM Table1/2/3
WHERE Table2.KEYVAL = TABLE1.KEYVAL
AND TABLE3.KEYVAL = TABLE2.KEYVAL
some WHERE's on Table 1,2,3
I also have some Subselects with a 4th Table in my Main Select Statement which work fast and fine.
Now i want to calculate the SUM of a Value in Table3 (let's call it weight).
Table3 Result has Multiple Rows (Sub-ID's) but share the Same KEY.
How can i accomplish that?
if i put a SubSelect in my Main Select:
(SELECT Sum(weight)
FROM Table3
WHERE Table3.KEYVAL = Table1.KEYVAL
) as Wheight
it get's ugly slow.
How can i (or does sql) differ between (Main)Table3.weight and (SubSelect)Table3.weight when i want to use a LeftJoin for that Weight?
Sum(weight) in Main Select does not work directly, i think because of not being DISTINCT?
I think you have to use the Group by function in your subquery.
For instance:
Select a.*, b.*
from mytable as a
join (select keyval, sum(weight) from my_second_table group by keyval) as b
on a.keyval = b.keyval

Use the result of a SQL query as an input for a WHERE clause

I wonder if (and how?) I can use the result set of a query as an input for a WHERE clause in another query.
For instance, I have a query that fetches a list of "code" and I would like to SELECT all tuples from another table that have - as "code" value - either one of the previously fetched set's elements.
I'm using JDBC so I wonder if I need to use some Java programming or If I can directly use SQL.
Select * from table2 -- this is another table from your question
where code in (select code from table1); -- this is where clause that gets code from first table.
In fact query is equivalent to:
Select t2.* from table2 t2
inner join table1 t1 on (t1.code = t2.code);
What in my opinion is better syntax.
Yes of course you can
Try this for example
SELECT f1 , f2 , f3 , etc
FROM table1
WHERE f1 IN (SELECT field1 FROM table2)
The in keyword is fine for finding a single code value into another table, but to associate multiple columns, you should use an inner join:
SELECT employees.name
FROM employees
INNER JOIN departments
ON employees.department = departments.department
AND employees.position = departments.position
WHERE departments.jobtitle = 'Manager'
Another example using in clause as per #Kacper's comment, not that not all databases support this syntax:
SELECT employees.name
FROM employees
WHERE (department,position) IN
(
SELECT department,position
FROM departments
WHERE jobtitle = 'Manager'
)

SQL Subquery w/LEFT JOIN causing Invalid Object Error

I have a query with the following structure:
EDIT Original structure of the query wasn't quite representative.
SELECT A
,B
,C
,D
FROM ( SELECT id,A
FROM myTable
WHERE conditions
GROUP BY id,A) MainQuery
LEFT JOIN (SELECT id, B, C
FROM myView
WHERE id IN
(
SELECT DISTINCT id
FROM MainQuery
)
) sub1
ON sub1.B = MainQuery.A
LEFT JOIN (SELECT MainQuery.id, D
FROM myOtherView
WHERE sub1.id IN
(
SELECT DISTINCT id
FROM MainQuery
)
) sub2
ON sub2.D = sub1.C
When I run the query, I get the error message Invalid object name 'MainQuery'. When I comment out the LEFT JOINs and the fields they feed in the SELECT statement, the query runs just fine. I've also tried AS MainQuery, but I get the same result.
I suspect it has something to do with scope. Where I'm trying to SELECT DISTINCT id FROM MainQuery, is MainQuery out of scope for the WHERE subquery within sub1?
For context, I've been tasked with rewriting a query that used temp tables into a query that can be used in a report deployed on SSRS 2000. My MainQuery, sub1, and sub2 were temp tables in the original query. Those temp tables used subqueries within them, which I've preserved in my translation. But the original query had the advantage of creating each temp table separately, and then joining the results. Temp tables and subqueries are new to me, so I'm not sure how to adapt between the two, or if that's even the right approach.
The SQL for your MainQuery is invalid. Run it by itself and see:
SELECT A, id
FROM myTable
WHERE conditions
GROUP BY A
You can't select A and id, but only group by A. Either you need to also group by id, or wrap id in an aggregate function like min, or max.
With that addressed it looks like your other issue is that you say "LEFT JOIN" but then place the column of your LEFT JOINED table on the left hand side of your where clause. See below where I flip sub1.B and MainQuery.A in the JOIN.
SELECT A
,B
,C
,D
FROM ( SELECT A, id
FROM myTable
WHERE conditions
GROUP BY A,id) MainQuery
LEFT JOIN nutherTable sub1
on MainQuery.A = sub1.B
and MainQuery.id = sub1.id
LEFT JOIN (SELECT D ...) sub2
ON sub1.C = sub2.D

Table.* notation does not work in a 'group by' query

On an oracle database, the Table.* notation does not work inside a 'select..group by..' query.
This query with no * works :
select A.id from TABLE_A A INNER JOIN TABLE_B B on A.id=B.aid group by A.id
This one with a * does not :
select A.* from TABLE_A A INNER JOIN TABLE_B B on A.id=B.aid group by A.id
The output is
00979. 00000 - "not a GROUP BY expression"
Why does this query not work? Is there a simple workaround?
Everything you selecting except agregate functions (MIN, MAX, SUM, AVG, COUNT...) must be in Group by
Yes, there is a workaround.
Assuming that each id in A is unique, then you don't even need to use group by, just:
select * from A
where id in (
select id from b
);
If id are not unique in A table, then you can simulate MySql functionality with this query:
select * from A
where rowid in (
select min( a.rowid )
from a
join b on a.id = b.id
group by a.id
);
Here is a link to SQL Fiddle demo
Here is a link to MySql documentation where their extension to group by is explained: http://dev.mysql.com/doc/refman/5.1/en/group-by-extensions.html
Pay attention to this fragment:
You can use this feature to get better performance by avoiding
unnecessary column sorting and grouping. However, this is useful
primarily when all values in each nonaggregated column not named in
the GROUP BY are the same for each group. The server is free to choose
any value from each group, so unless they are the same, the values
chosen are indeterminate. Furthermore, the selection of values from
each group cannot be influenced by adding an ORDER BY clause. Sorting
of the result set occurs after values have been chosen, and ORDER BY
does not affect which values within each group the server chooses.
A group by expression must include all the columns you select. So, if the table has 3 columns (column1, column2 and column3), you have to group by all of them like this: group by Column1, Column2, Column3. The * means you select all the columns, so add all of them in the group by expression.

EXCEPT keyword in Oracle

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