Spooky query behavior : Same query, different results when inside a view - sql

The same query brings different results when inside a View.
I tried to force same codepages, same data types, Common Query Expressions... none worked.
Have a look at this simple query:
SELECT TOP 100 CompanyID, SubsidiaryID
FROM STAGING.SALESAX S
INNER JOIN Subsidiary SU
ON S.CompanyID = SU.SubsidiaryAXCode
It returns all expected 100 rows.
If I use the EXACT SAME QUERY in a view:
CREATE VIEW [STAGING].[VSalesAXBASE]
AS
SELECT TOP 100 CompanyID, SubsidiaryID
FROM STAGING.SALESAX S
INNER JOIN Subsidiary SU
ON S.CompanyID = SU.SubsidiaryAXCode
GO
SELECT * FROM [STAGING].[VSalesAXBASE]
it returns 0 ROWS

You prefix SALESAX table with STAGING., but don't prefix Subsidiary table in the query. Do prefix all tables in the query.
One possibility is that there are several Subsidiary tables and the query uses different table in the context of the view.
By the way, it is also a good practice to prefix columns with table names in the SELECT part of the query. For example, right now it is hard to know from which table(s) the columns CompanyID and SubsidiaryID come from.

The solution was to add the DBO schemma to the subsidiary table.. thanks to the suggestions of #VladimirBaranov, #IMSoP and #Augustina(Codec)
Looks like the execution context of the view may be different from the current user (need to check more on this).

SQL does not guarantee the ordering of results unless an explicit Order By clause is used.

Related

Best way to "SELECT *" from multiple tabs in sql without duplicate?

I am trying to retrieve every data stored in 2 tabs from my database through a SELECT statement.
The problem is there are a lot of columns in each tab and manually selecting each column would be a pain in the ass.
So naturally I thought about using a join :
select * from equipment
join data
on equipment.id = data.equipmentId
The problem is I am getting the equipment ID 2 times in the result.
I thought that maybe some specific join could help me filter out the duplicate key, but I can't manage to find a way...
Is there any way to filter out the foreign key or is there a better way to do the whole thing (I would rather not have to post process the data to manually remove those duplicate columns)?
You can use USING clause.
"The USING clause specifies which columns to test for equality when
two tables are joined. It can be used instead of an ON clause in the
JOIN operations that have an explicit join clause."
select *
from test
join test2 using(id)
Here is a demo
You can also use NATURAL JOIN
select *
from test
natural join test2;

What is the difference between using '*' and '.*' in the first line of a select statement?

I'm hoping if someone could explain the difference between the two following statements:
SELECT * FROM employee;
and
SELECT employee.* FROM employee;
If someone could provide their reasoning for choosing employee.* instead of *, or when it would be appropriate to choose one over the other, it would be greatly appreciated.
Kind regards,
Joe.
SELECT * ...
selects all columns from the result set generated in the FROM clause.
SELECT employees.* ...
selects all columns in the result set generated in the FROM clause that originated from the employees table (note that employees may also be an alias rather than a table name).
When the FROM clause only contains a single table, those two describe the same set of columns.1
As to why someone has chosen to write it this way when only a single table is present, I couldn't say. If they were an absolutist who insisted on prefixing all columns in the select clause with their originating table, I'm surprised that they're comfortable using * in there at all rather than explicit column names.
1But note that it's the FROM clause (including any JOINs etc) and the WHERE, GROUP BY and HAVING clauses that affect which rows are displayed. The SELECT clause effectively chooses columns.
In your example there is no difference. The reason the syntax allows for this is to allow you to display all the columns from only one object in your FROM clause. It would make more sense with an example.
The following query will display all columns from both tables employee and manager
SELECT * FROM employee inner join manager on employee.managerid = manager.managerid
The following query is functionally equivalent to the one above it the difference being is that we explicitly specify the order of the tables in the displayed column set.
SELECT employee.*, manager.* FROM employee inner join manager on employee.managerid = manager.managerid
The following query will only display columns from table employee and not manager
SELECT employee.* FROM employee inner join manager on employee.managerid = manager.managerid

Query returns different results depending on number of tables in FROM

I have several tables in a exercise, lets call them animals, prizes and exhibitions.
When I write following simple query
SELECT animals.name FROM animals;
I get 8 results, all names from the animals table.
However when I write
SELECT animals.name FROM animals, exhibitions, prizes;
I get over six hundred results, all of them names from animals table, just multiple times.
Why is that happening? I specified the column and the table in the SELECT command. I do not want any data from other tables.
Only table animals has a column called name.
Edit: Sorry I asked.
You are performing a union join, which 'multiplies' the tuples in all the tables regardless of whether or not they have common fields. You need to specify a join field in your SQL, else you get this type of join.
when you join several tables you will got the result of all tables, in your example you got not only animal table , you aslo got exhibitions and prizes.
to solve that use a specifque condition example .. where animal.name = exhibitions.place
read more about joins fromt oracle document ( left joins , outer joins) its really helpful

SQL Repetition, how to avoid in query?

I'm trying to get the names and the addresses that are stored in the table but getting data repetition. I dont know how to avoid it as im a newbie to this field. here's some pictures of the commands and results.
Commands:
Results:
Owner Table:
Addresses Table:
Please help me out :(
P.S. They are all dummy data.
You need to do a join between the two tables owners and addresses using column in tables that referenece each other.
SELECT firstname,lastname,addressline_1
FROM owners o
JOIN addresses a
ON o.colName=a.colName
Your query is performing cartesian product between the two tables which is giving all rows for table address for each row in table owners.
You would have avoided getting meaningless rows had you used recommended ANSI SQL syntax of performing join using ON clause rather than WHERE clause . Although you haven't specified condition for joining between the tables still old syntax of joining using WHERE clause got executed successfully but would have thrown error in case of using ON clause.
See this thread for detailed discussion ON vs WHERE
EDIT
As per your schema of tables the query would be
SELECT firstname,lastname,addressline_1
FROM owners o
JOIN addresses a
ON o.ownerid=a.owners_ownerid
you have to add where clause to your query:-
SELECT OWNERS.first_name, OWNERS.last_name, ADDRESSES.address_line1
FROM OWNERS, ADDRESSES
WHERE OWNERS.ownerid = ADDRESSES.owners_ownerid
or you can use join
SELECT OWNERS.first_name, OWNERS.last_name, ADDRESSES.address_line1
FROM OWNERS
JOIN ADDRESSES
ON OWNERS.ownerid = ADDRESSES.owners_ownerid

Why is selecting specified columns, and all, wrong in Oracle SQL?

Say I have a select statement that goes..
select * from animals
That gives a a query result of all the columns in the table.
Now, if the 42nd column of the table animals is is_parent, and I want to return that in my results, just after gender, so I can see it more easily. But I also want all the other columns.
select is_parent, * from animals
This returns ORA-00936: missing expression.
The same statement will work fine in Sybase, and I know that you need to add a table alias to the animals table to get it to work ( select is_parent, a.* from animals ani), but why must Oracle need a table alias to be able to work out the select?
Actually, it's easy to solve the original problem. You just have to qualify the *.
select is_parent, animals.* from animals;
should work just fine. Aliases for the table names also work.
There is no merit in doing this in production code. We should explicitly name the columns we want rather than using the SELECT * construct.
As for ad hoc querying, get yourself an IDE - SQL Developer, TOAD, PL/SQL Developer, etc - which allows us to manipulate queries and result sets without needing extensions to SQL.
Good question, I've often wondered this myself but have then accepted it as one of those things...
Similar problem is this:
sql>select geometrie.SDO_GTYPE from ngg_basiscomponent
ORA-00904: "GEOMETRIE"."SDO_GTYPE": invalid identifier
where geometrie is a column of type mdsys.sdo_geometry.
Add an alias and the thing works.
sql>select a.geometrie.SDO_GTYPE from ngg_basiscomponent a;
Lots of good answers so far on why select * shouldn't be used and they're all perfectly correct. However, don't think any of them answer the original question on why the particular syntax fails.
Sadly, I think the reason is... "because it doesn't".
I don't think it's anything to do with single-table vs. multi-table queries:
This works fine:
select *
from
person p inner join user u on u.person_id = p.person_id
But this fails:
select p.person_id, *
from
person p inner join user u on u.person_id = p.person_id
While this works:
select p.person_id, p.*, u.*
from
person p inner join user u on u.person_id = p.person_id
It might be some historical compatibility thing with 20-year old legacy code.
Another for the "buy why!!!" bucket, along with why can't you group by an alias?
The use case for the alias.* format is as follows
select parent.*, child.col
from parent join child on parent.parent_id = child.parent_id
That is, selecting all the columns from one table in a join, plus (optionally) one or more columns from other tables.
The fact that you can use it to select the same column twice is just a side-effect. There is no real point to selecting the same column twice and I don't think laziness is a real justification.
Select * in the real world is only dangerous when referring to columns by index number after retrieval rather than by name, the bigger problem is inefficiency when not all columns are required in the resultset (network traffic, cpu and memory load).
Of course if you're adding columns from other tables (as is the case in this example it can be dangerous as these tables may over time have columns with matching names, select *, x in that case would fail if a column x is added to the table that previously didn't have it.
why must Oracle need a table alias to be able to work out the select
Teradata is requiring the same. As both are quite old (maybe better call it mature :-) DBMSes this might be historical reasons.
My usual explanation is: an unqualified * means everything/all columns and the parser/optimizer is simply confused because you request more than everything.