Access SQL SELECT Query: Required to use the table alias in WHERE clause? - sql

Current Environment: Split Access Database, Local Access Front End, Access Backend on shared network drive
I'm writing a stupid long SELECT statement. Using table aliases to makes my code more readable.
I was taught to write out full table names in WHERE statements because they are executed before the FROM statement. However, when I did that - Access isn't finding the table / field referenced when I write the full table name out. Strangely, I tried using the alias in the WHERE statement and it works!!?
Does Access execute the statement differently than I was taught? Or am I unknowingly causing it to do it this way?
Shortened version of my SQL code that doesn't work:
SELECT [C].Multi_File_Case_ID,
[C].Case_Report_Number,
[C].Include_In_Casebook,
[C].Case_Status,
FROM Case_Tbl AS [C]
WHERE [Case_Tbl].Include_In_Casebook = True;
Edit: A word and a capitalization ;)

Once you define a table reference as an alias in the FROM, you need to use that alias everywhere in the query. The alias is more than a nickname; it is a name change for the scope of the query.
I would advise you to drop the square braces. Queries are easier to read and write as:
SELECT c.Multi_File_Case_ID, c.Case_Report_Number, c.Include_In_Casebook, c.Case_Status
FROM Case_Tbl AS c
WHERE c.Include_In_Casebook = True;
When you do not define a table alias, the table name itself serves as the alias.

Related

How can I control the SQL table aliases that Hibernate uses in its generated queries?

tl;dr: Hibernate automatically generates SQL table aliases in its queries like jurisdicti4_ or this_. Here's an example query:
SELECT
this_.id AS id2_6_3_,
this_.a_table_column AS a_table_column3_6_3_,
jurisdicti4_.b_table_column AS b_table_column4_6_3_,
FROM
app_table_a this_
LEFT OUTER JOIN jurisdiction jurisdicti4_ ON this_.jurisdiction = jurisdicti4_.name
WHERE
this_.a_table_column = ?
I'm using the Hibernate Criteria API to add some hints that need reference the SQL aliases in the query, so I need to know how to either:
specify the SQL table aliases Hibernate will use in its queries (e.g. tell it to use juris instead of jurisdicti4_ for jurisdiction, or
get hibernate to tell me the exact SQL table alias it will use for a particular table or entity (e.g. be told the alias in the query for jurisdiction will be jurisdicti4_.
Full story:
I've inherited a Java app with an Oracle DB that uses Hibernate 4.3.8 and the Hibernate Criteria API to generate some complicated search queries. It recently ran into a severe SQL performance problem that will require us to start to include hints these queries. However, we use Oracle, and its index hints are in the form of:
/*+ index (TABLE_ALIAS INDEX_NAME) */
I've successfully added the needed hints using Criteria.addHint(...), however I've had to hardcode the Hibernate-generated TABLE_ALIAS in the hint string. I'm concerned that over time, the aliases may change, so I want to either control how they're generated or be able to retrieve their values to use when adding the SQL hint.
Edit: This website describes the Hibernate SQL alias generation process: https://prismoskills.appspot.com/lessons/Hibernate/Chapter_23_-_Hibernate_alias_names.jsp
I've found that I have partial control of the SQL aliases when I programmatically set up the join like this: criteria.createAlias(associationPath, alias). The alias value I pass seems to be used as the first part of the SQL alias for the table. However, Hibernate appends some kind of generated table ID integer to that, so I'd get something like myalias4_ in the generated SQL. Also, this only seems to work in joins I setup myself in the criteria. Hibernate will often add its own based on the mappings, and I'm not sure how get this same level of partial control over those.

How do I deal with identically named fields in the source database, differentiated only by label name?

The database setup at my organisation is SQL tables copied onto our SAS server. The SQL tables were setup to run pre-programmed SQL queries, now SAS is the tool used. This however creates an issue with some tables having variables that are too long for SAS, but work in SQL. The label for the source variable is correct and not shortened.
The source table (in SQL Server) names:
Consolidated_Arrears_Vs_Portfolio_Balance_Ltd
Consolidated_Arrears_Vs_Portfolio_Balance_Pure
In SAS:
Consolidated_Arrears_Vs_Portfoli
Consolidated_Arrears_Vs_Portfoli
SAS Labels:
Consolidated_Arrears_Vs_Portfolio_Balance_Ltd
Consolidated_Arrears_Vs_Portfolio_Balance_Pure
So, how do I tell the difference in code between these two?
Thanks in advance.
To use the data as native in SAS, one approach would be to write a macro to map the original SQL names (per label) to the corresponding new SAS names. If the original table names got mangled as well you have a lot more issues.
Original SQL
select Abracadabra_Magical_Unity_Formation_SequenceId from AMUF_Master
Replace with
select %nameFor(Abracadabra_Magical_Unity_Formation_SequenceId) from AMUF_Master
The macro %nameFor would either do a dynamic lookup against the tables in the library, or perhaps better, when a static table design, create a fixed mapping table from a one time lookup
* presume SQL data now in libref MIGRATED;
* do once to get the variable metadata that includes LABEL and NAME;
proc sql;
create table static.nameFor as
select * from sashelp.vcolumn
where libnames = 'MIGRATED';
* use as needed;
%macro nameFor(SQL_Name);
%sysfunc(dosubl(select NAME from static.nameFor where LABEL="&SQL_Name"))
%mend;
You could also use the static.nameFor to discover all the SQL names that got changed during migration. Those would be where name ne label.
An automated approach would be to create a search and replace program that makes changes to a copy of the original SQL queries on-hand.
The search and replace would be either
find <long-named column>, replace with %nameFor(<long-named column>) , or
find <long-named column>, replace with <migrated to SAS column name>
The first replacement way adds noise.
The second way loses some of the original queries 'true-flavor'

SQLite given a statement it is possible to know what table will be touched [duplicate]

I am using sqlite in a C++ project and I would like to be able to get the table names involved in a query.
Ex:
SELECT * FROM Employee
should return Employee
Now I use successfully qlite3_column_table_name (doc) for this kind of queries but for aggregate queries, the function returns null as the result does not belong to a table directly.
ex:
SELECT SUM(salary) AS total FROM Employee
Surely, when sqlite compiles the statement, the "Employee" keyword is recognised as a table. Do you know aby way to have access to this?
I tried to step through the code of the parser without success...
An authorizer callback allows you to detect which tables are actually accessed by a query.

SQL select from table with alias (Oracle9i)

According to Oracle documentation for statement SELECT it should be possible to alias table names with aliases without or with keyword AS. However, aliasing tables with keyword AS leads to error:
ORA-00933: SQL command not properly ended
For example, the following statement fails with the above error:
SELECT COUNT(*) FROM MY_TABLE AS A;
Once keyword AS is removed it executes as expected.
Could anyone please comment on this. Is there a way to make the application of AS for table aliasing work?
P.S. I'm using a code generation utility that translate some Java code into SQL statements at runtime. This utility enforces the use of aliases with AS.
Oracle does not accept AS for table aliases and I see no way to make it work.
Can't you do anything in Java? AS for column aliases is optional in Oracle, so you could look for all " AS " in the generated string and remove them (thus removing AS for column aliases as well as for table aliases). Is this an option?

MS Access SQL DELETE - why would someone specify column names?

I'm having to support an Access .mdb file that someone else has written. One of the button functions in this .mdb calls out to delete some data in an external MSSQL database. All very straightforward, but this syntax isn't something I've seen before:
DELETE
tblEquipmentConnections.SourceEquip,
tblEquipmentConnections.EquipmentConnectionID
FROM tblEquipmentConnections
WHERE
tblEquipmentConnections.SourceEquip = [Forms]![frmEquipment]![EquipmentID];
Is that any different than this?
DELETE
FROM tblEquipmentConnections
WHERE
tblEquipmentConnections.SourceEquip = [Forms]![frmEquipment]![EquipmentID];
I can't find a case where specifying specific columns does anything - but I don't spend much time in Access, so I'm not sure how different the SQL syntax is...
Thanks!
Specifying the column names makes no difference. It's just an Access thing.
The reason they might be there is because Access used to generate DELETE statements that way (not sure if it still does).
The second form without columns names is obviously preferable.
I think the query has been built directly into Access query editor.
And generally we begin by building a select query. Then we change the query type from "Select query" to "Delete query". Then we display the query source by selecting "SQL Mode" where we copy / paste a sql statement like this one :
DELETE qc_Boxes.idBox, qc_Boxes.idScreen, qc_Boxes.title
FROM qc_Boxes;
This is absolutely redundant. The place between DELETE and FROM is used only when the deletion is performed based on a multi-table condition, but even in this case it contains table names and not field names. Also it can contain * which is also redundant. In MySQL, for example it's an incorrect syntax.