ERROR in CREATE VIEW - sql

I tried to create a new view in my MS Access database so I can select better from it but I wonder what's happening here.
CREATE VIEW new
AS
SELECT msthread.id,
msthread.threadname,
Count(msthread.threadname) AS TotalPost,
threadcategory
FROM msthread
LEFT OUTER JOIN msposts
ON msthread.threadname = msposts.threadname
GROUP BY msthread.id,
msthread.threadname,
msthread.threadcategory
Access gives me this error message when I try to execute that statement.
Syntax error in create table statement
Is there specific problems in creating view with JOINs? I'm trying to access 2 tables.

CREATE VIEW was introduced with Jet 4 in Access 2000. But you must execute the statement from ADO/OleDb. If executed from DAO, it triggers error 3290, "Syntax error in CREATE TABLE statement", which is more confusing than helpful.
Also CREATE VIEW can only create simple SELECT queries. Use CREATE PROCEDURE for any which CREATE VIEW can't handle.
But CREATE VIEW should handle yours. I used a string variable to hold the DDL statement below, and then executed it from CurrentProject.Connection in an Access session:
CurrentProject.Connection.Execute strSql
That worked because CurrentProject.Connection is an ADO object. If you will be doing this from outside Access, use an OleDb connection.
Notice I made a few changes to your query. Most were minor. But I think the query name change may be important. New is a reserved word so I chose qryNew instead. Reserved words as object names seem especially troublesome in queries run from ADO/OleDb.
CREATE VIEW qryNew
AS
SELECT
mst.id,
mst.threadname,
mst.threadcategory,
Count(mst.threadname) AS TotalPost
FROM
msthread AS mst
LEFT JOIN msposts AS msp
ON mst.threadname = msp.threadname
GROUP BY
mst.id,
mst.threadname,
mst.threadcategory;

Going out on a limb here without the error message but my assumption is that you need an alias in front of your non-aliased column.
You may also have a problem titling the view as new. This is a problem with using a generic name for a view or table. Try giving it a distinct name that matters. I'll use msThreadPosts as an example.
CREATE VIEW msThreadPosts
AS
SELECT msthread.id,
msthread.threadname,
Count(msthread.threadname) AS TotalPost,
msposts.threadcategory --Not sure if you want msposts or msthread just pick one
FROM msthread
LEFT OUTER JOIN msposts
ON msthread.threadname = msposts.threadname
GROUP BY msthread.id,
msthread.threadname,
msthread.threadcategory
As long as we are looking at this query lets fix some other things that are being done in a silly way.
Lets start off with aliasing. If you alias a column you can very easily make your query easy to understand and read to anyone who is inclined to read it.
CREATE VIEW msThreadPosts
AS
SELECT mt.id,
mt.threadname,
Count(mt.threadname) AS TotalPost,
mp.threadcategory
FROM mtas mt
LEFT OUTER JOIN msposts mp
ON mt.threadname = mp.threadname
GROUP BY mt.id,
mt.threadname,
mt.threadcategory
There now doesn't that look better.
The next thing to look as if your column names. msthread has an id column. That column name is incredibly generic. This can cause problems when a column isn't aliased and an id exists in mulitple places or there are muliple id columns. Now if we change that column name to msthreadID it makes things much clearer. The goal is to design your tables in a way that anyone working on your database can imidiatley tell what a column is doing.
The next thing to look at is your join. Why are you joining on thread name? threadname is likely a character string and therefore not terribly efficient for joins. if msthread as an id column and needs to be joined to msposts then shouldn't msposts also have that id column to match up on to make joins more efficient?

Related

Access Query link two tables with similar values

I am trying to create a select query in access with two tables I want to link/create a relationship.
Normally, if both tables contains same value you can just "drag" and create a link between those two columns.
In this case however, the second table have an " /CUSTOMER" added at the end in the fields.
Example;
Table1.OrderNumber contains order numbers which always contains 10 characters
Table2.Refference contains same order numbers, but will have a " /CUSTOMER" added to the end.
Can I link/create a relationship between these two in a Query? And how?
Thanks for the help!
Sebastian
Table1.OrderNumber contains order numbers which always contains 10 characters
If so, try this join:
ON Table1.OrderNumber = Left(Table2.Reference, 10)
For these nuanced joins you will have to use SQL and not design view with diagram. Consider the following steps in MS Access:
In Design view, create the join as if two customer fields match exactly. Then run the query which as you point out should return no results.
In SQL view, find the ON clause and adjust to replace that string. Specifically, change this clause
ON Table1.OrderNumber = Table2.Refference
To this clause:
ON Table1.OrderNumber = REPLACE(Table2.Refference, '/CUSTOMER', '')
Then run query to see results.
Do note: with this above change, you may get an Access warning when trying to open query in Design View since it may not be able to be visualized. Should you ignore the warning, above SQL change may be reverted. Therefore, make any changes to query only in SQL view.
Alternatively (arguably better solution), consider cleaning out that string using UPDATE query on the source table so the original join can work. Any change to avoid complexity is an ideal approach. Run below SQL query only one time:
UPDATE Table2
SET Refference = REPLACE(Refference, '/CUSTOMER', '')

Multiple Left Joins in the same query causes "Invalid Operation" Error

I have the following queries ...
Query #1
SELECT aa.DocNum, b.QualityClass
FROM dbo_TransferHistory AS aa LEFT JOIN PCQualityClass AS bb ON aa.DocNum = bb.DocumentNum
WHERE (((aa.DocNum)=[Enter Doc Num]));
Query #2
SELECT aa.DocNum, bb.QualityClass, cc.BldgCond
FROM (dbo_TransferHistory AS aa LEFT JOIN PCQualityClass AS bb ON aa.DocNum = bb.DocumentNum)
LEFT JOIN PCBldgCond AS cc ON aa.DocNum = cc.DocumentNum
WHERE (((aa.DocNum)=[Enter Doc Num]));
dbo_TransferHistory is an table I access through an ODBC connector.
PCQualityClass and PCBldgCond are two queries that are based off another ODBC table. Both of these queries have only the two respective fields referenced in the main query.
DocNum and DocumentNum are the same type ("Short Text" and a length of 12) and while I would like to make the names the same, I cannot.
When the query is run, an Inputbox pops up and [Enter Doc Num] is replaced with the Document Number I want the data for.
The queries were created in Access using the Create Query tool.
The problem is that while Query #1 will work, Query #2 causes the error "Invalid Operation".
Changing to inner joins will allow Query #2 to function but will cause issues as there are times that one or both of the two sub queries do not have data but I still need the data from the primary table.
Please help, I am at my wits end as to why this is not working. Is this an Access 2013 bug that will not allow for two Left Joins in the same query or something else I am missing?
The SQL looks like it should work, so the problem is probably the combination of the base queries plus the two left joins.
My general experience with Access queries on ODBC tables and with multiple outer joins is: even if you get them to work, they usually perform pretty badly.
So my suggestion is: Re-create the whole thing as view on SQL Server, and link that view. Then your Access query becomes something trivial like
SELECT * FROM dbo_ViewTransferHistory
WHERE DocNum=[Enter Doc Num]
Ok, so this is frustrating the absolute !##$% out of me. The syntax is correct and everything I see online says it should work. Out of pure frustration and some curiosity, I imported the ODBC tables into Access as local tables and changed the table references in the queries to use the local tables. OMG, now it works. Same data, same structure, different table type, and it !##$ing works. So it looks like the problem is in attempting to make multiple joins using ODBC. Unfortunately, I cannot create local tables from the ODBC every time this query gets run. Going to keep looking into this and see if I can find another workaround. Any other ideas?
Basically, Access will not allow multiple Outer Joins when using ODBC data sources. I am going to mark this as answered and rephrase the question in a new post.
Thank you.

Having Trouble Running An SQL Update Statement

Forgive me but I'm relatively new to SQL.
I am trying to update a column of a table I created with a function I created but when I run the Update Statement, nothing happens, I just see the underscore flashing (I'm assuming its trying to run it). The Update Statement is updating around 60,000 fields so I assume it should take a little while but it's been 10 minutes and no good.
I would just like to know if anyone knows just some general reasons that the underscore may be flashing. I know this is super general but I've just never seen this before.
Here's an image of what I'm talking about:
http://i.imgur.com/Xk3kM2U.png?1
EDIT: There are exactly 67,662 records in the table.
I've also just screenshotted the query and linked it.
Your old-style joins have no join condition between the ap1/r1 pair and the ap2/r2 pair, so you're calling your calc_distance() function for 67,662 * 67,622 combinations of coordinates. The use of distinct is potentially a warning that you know you're getting duplicates. And then there is no correlation between the subquery and the update itself, so you're repeating that for each row in temproute. That will take a while.
It looks like you maybe don't want to be looking at the source airport from two copies of the route table; but the source and destination airports from a single copy.
Something like (untested):
UPDATE temproute tr
SET distance = (
SELECT calc_distance(ap2.latitude, ap2.longitude, ap1.latitude, ap1.longitude)
FROM routes r
JOIN airports ap1 ON ap1.icaoairport = r.sourceid
JOIN airports ap2 ON ap2.icaoairport = r.destid
WHERE r.routeid = tr.routeid
);
If temproute is a copy of route too, which the line count implies, then you don't need to refer to route directly at all in the subquery, perhaps.
But I'm speculating about what you're doing.

SQL Developer "disconnected from the rest of the join graph"

I have the following SQL:
select <misc things>
from pluspbillline
left outer join workorder
on workorder.siteid=pluspbillline.siteid
and workorder.wonum = pluspbillline.refwo
and workorder.orgid = pluspbillline.orgid
left outer join ticket
on ticket.ticketid = pluspbillline.ticketid
and ticket.class=pluspbillline.ticketclass
left outer join pluspsalesorder
on pluspsalesorder.salesordernum=pluspbillline.salesordernum
and pluspsalesorder.siteid=pluspbillline.siteid
In Oracle SQL Developer 4.0.0.13 (connected to a DB2 database), I get a squiggly line underneath the following italics: "from pluspbillline" and "left outer join workorder".
The warning says "pluspbillline is disconnected from the rest of the join graph". What does this mean?
I got this as well. I'm not exactly sure how to articulate it but the error seems to be based on the logical flow of the code.
Essentially because you mention the table pluspbillline before workorder I think it expects the join to be on pluspbillline.siteid=workorder.siteid etc.
It seems that the order of the conditions for joins should flow from the first identified tables to the latest ones. So the following should make it happy:
plusbillline to workorder on pluspbillline.siteid=workorder.siteid...
"" to ticket on pluspbillline.ticketid = ticket.ticketid...
"" to pluspsalesorder on pluspbillline.salesordernum = pluspsalesorder.salesordernum...
I don't believe this would change the work oracle does (assuming you don't use optimizer hints) so I'd only bother to change if you hate the squiggly lines.
I'm not sure what's causing Oracle SQL Developer to give the error. But I'm putting this comment here to format it properly.
A join graph might look something like this
pluspbillline ------+----< workorder
|
+----< ticket
|
+----< pluspsalesorder
The lines on the graph might be labeled with the join fields. But this gives you a basic idea.
I don't see any reason why you are getting this warning. A column name typo in your SQL perhaps? Or some quirk in Oracle's interface that it doesn't understand the DB2 metadata properly? I suggested trying IBM's tool to see if it's merely their program.
The issue is caused by the Oracle Procedure having the same named input parameter as the column on the table you are joining to.
i.e input parm named bank_nbr and a table BankDept.bank_nbr will cause the error if you have WHERE bank_nbr = BankDept.bank_nbr
I solved the issue by renaming the input parameter to in_bank_nbr and updating my where to read WHERE in_bank_nbr = BankDept.bank_nbr
I had the same message when hovering over the "LEFT" word, but the whole query ran without a problem. On the other hand, when I hovered over "WITH", I got a piece of advice about restructuring the whole query. So, that message about disconnection could be not a sign of an error, but a warning about a too complex sentence. SQLDeveloper's editor does not mention the level of the problem.

Oracle DB simple SELECT where column order matters

I am doing a simple SELECT statement in an Oracle DB and need to select the columns in a somewhat-specific order. Example:
Table A has 100 attributes, one of which is "chapter" that occurs somewhere in the order of columns in the table. I need to select the data with "chapter" first and the remaining columns after in no particular order. Essentially, my statement needs to read something like:
SELECT a.chapter, a. *the remaining columns* FROM A
Furthermore, I cannot simply type:
SELECT a.chapter, a.*
because this will select "chapter" twice.
I know the SQL statement seems simple, but if I know how to solve this problem, I can extrapolate this thought into more complicated areas. Also, let's assume that I can't just scroll over to find the "chapter" column and drag it to the beginning.
Thanks.
You should not select * in a program. As your schema evolves it will bring in things you do not know yet. Think about what happens when someone add a column with the whole book in it? The query you thought would be very cheap suddenly starts to bring in megabytes of data.
That means you have to specify every column you need.
Your best bet is just to select each column explicitly.
A quickie way to get around this would be SELECT a.chapter AS chapterCol, a.* FROM table a; This means there will be one column name chapterCol (assuming there's not a column already there named chapterCol. ;))
If your going to embed the 'SELECT *' into program code, then I would strongly recommend against doing that. As noted by the previous authors, your setting up the code to break if a column is ever added to (or removed from) the table. The simple advice is don't do it.
If your using this in development tools (viewing the data, and the like). Then, I'd recommend creating a view with the specific column order you need. Capture the output from 'SELECT COLUMN_NAME FROM ALL_TAB_COLUMNS' and create a select statement for the view with the column order you need.
This is how I would build your query without having to type all the names in, but with some manual effort.
Start with "Select a.chapter"
Now perform another select on your data base as follows :
select ','|| column_name
from user_tab_cols
where table_name = your_real_table_name
and column_name <> 'CHAPTER';
now take the output from that, in a cut-and-paste manner and append it to what you started with. Now run that query. It should be what you asked for.
Ta-da!
Unless you have a very good reason to do so, you should not use SELECT * in queries. It will break your application every time the schema changes.