(1) The Access Database is being used as way to connect to 2 Teradata databases
(2) Currently it has 6 linked tables to 2 Teradata databases
(3) It doesn't matter to me if it is an Access Query or a pass-through query to Teradata
(4) The goal is to put something in an Excel macro that will query the 2 Teradata bases and return some information that will be included in a macro
I'm trying to create a SQL query in Access with SQL that works in Teradata. When I try to run the query, I get am error message (Syntax error in FROM clause) and the 1st Join is highlighted. I've written queries in Access before but nothing this complex. We are using Access 2010. Any suggestions on the syntax error would be greatly appreciated. Thanks for the help.......
select veh_mgmt_csr.cst_bo_item.veh_lgcy_nbr as unit, veh_mgmt_csr.cst_bo_item.veh_odmtr_qty as mileage, veh_mgmt_csr.rm_cust_mast.upp_lgl_cust_nam as cust_legal_name, veh_mgmt_csr_rv.cst_address.addr_st_nam as address,
veh_mgmt_csr_rv.cst_address.addr_cty_nam as city, veh_mgmt_csr_rv.cst_address.addr_postl_cde as zip, veh_mgmt_csr_rv.cst_address.stprov_cde as state, veh_mgmt_csr_rv.cst_address.cntry_iso_cde as country, veh_mgmt_csr_rv.cst_address.addr_phn_nbr as location_phone, e.contact_name, e.contact_phone
from veh_mgmt_csr.cst_buyer_order
Join veh_mgmt_csr.cst_bo_item on veh_mgmt_csr.cst_buyer_order.bo_id = veh_mgmt_csr.cst_bo_item.bo_id and veh_mgmt_csr.cst_bo_item.veh_invy_stat_dsc = 'SOLD'
Join veh_mgmt_csr.rm_cust_mast on veh_mgmt_csr.cst_buyer_order.rm_cust_id = veh_mgmt_csr.rm_cust_mast.rm_cust_id
Join VEH_MGMT_CSR_RV.cst_address on veh_mgmt_csr.rm_cust_mast.prim_addr_id = veh_mgmt_csr_rv.cst_address.addr_id and veh_mgmt_csr_rv.cst_address.record_status = 'A'
left join (select veh_mgmt_csr.cst_buyer_order.e_o_id cust_nbr,trim(veh_mgmt_csr.cst_individual.indiv_upp_frst_nam) || ' ' || trim(veh_mgmt_csr.cst_individual.indiv_upp_last_nam) contact_name,
VEH_MGMT_CSR_RV.CST_PHONE_NBR.phn_nbr contact_phone from veh_mgmt_csr.cst_e_o_cntct
left join veh_mgmt_csr.cst_individual on veh_mgmt_csr.cst_e_o_cntct.indiv_id = veh_mgmt_csr.cst_individual.indiv_id
left join VEH_MGMT_CSR_RV.CST_PHONE_NBR on veh_mgmt_csr.cst_e_o_cntct.indiv_id = VEH_MGMT_CSR_RV.CST_PHONE_NBR.indiv_id and VEH_MGMT_CSR_RV.CST_PHONE_NBR.prim_phn_ind = 1
qualify rank() over (partition by veh_mgmt_csr.cst_e_o_cntct.e_o_id order by contact_name asc) = 1) e on veh_mgmt_csr.rm_cust_mast.rm_cust_id = e.cust_nbr
where veh_mgmt_csr.cst_individual.veh_lgcy_nbr = '8B5RG1'
and veh_mgmt_csr.cst_e_o_cntct.cntry_iso_cde in ('US','CA')
and extract(year from veh_mgmt_csr.cst_e_o_cntct.bo_dte) = 2017
As a beginner to SQL, please note that while most RDBMS's including MS Access and Teradata may run ANSI-SQL (basic, standard DDL/DML statements), almost no two RDBMS's share the same dialects (ANSI-plus). Each maintains their own styles and specific methods.
Additionally, do note MS Access comes in two folds: 1) a GUI .exe application and 2) a database engine (ACE/JET database engine). Over time it has been conflated to be the same but they are not. See this meta post. The former .exe application by default connects to the default database engine but this default can be switched out for other backends like Teradata.
However, the method of connection between frontend GUI and backend database (i.e., linked tables, pass-through queries, application code) will differ in the SQL dialect used.
linked tables => MS Access SQL dialect
pass-through queries => Backend RDBMS database dialect
application code (i.e., VBA) => Backend RDBMS database dialect
You may be attempting to run Teradata SQL on MS Access linked tables, hence violating #1 with resulting syntax errors. As seen below with proper indentation, there are several incompatible syntaxes in your attempted query:
MS Access uses only one period qualifier between table name and column name. Likely you may be referencing a named schema, only available in Teradata.
MS Access does not use JOIN by itself but requires INNER, LEFT, or RIGHT (no OUTER);
MS Access requires parentheses whenever pairs of tables are used in JOIN clauses;
MS Access does not support window functions such as RANK() OVER...;
MS Access uses & in concatenation not double pipes || and uses Year() instead of extract(year ...); and does not use qualify, possibly strictly a Teradata method;
MS Access requires AS for column aliases such as for contact_name and contact_phone.
SQL
SELECT veh_mgmt_csr.cst_bo_item.veh_lgcy_nbr AS unit,
veh_mgmt_csr.cst_bo_item.veh_odmtr_qty AS mileage,
veh_mgmt_csr.rm_cust_mast.upp_lgl_cust_nam AS cust_legal_name,
veh_mgmt_csr_rv.cst_address.addr_st_nam AS address,
veh_mgmt_csr_rv.cst_address.addr_cty_nam AS city,
veh_mgmt_csr_rv.cst_address.addr_postl_cde AS zip,
veh_mgmt_csr_rv.cst_address.stprov_cde AS state,
veh_mgmt_csr_rv.cst_address.cntry_iso_cde AS country,
veh_mgmt_csr_rv.cst_address.addr_phn_nbr AS location_phone,
e.contact_name,
e.contact_phone
FROM veh_mgmt_csr.cst_buyer_order
JOIN veh_mgmt_csr.cst_bo_item
ON veh_mgmt_csr.cst_buyer_order.bo_id = veh_mgmt_csr.cst_bo_item.bo_id
AND veh_mgmt_csr.cst_bo_item.veh_invy_stat_dsc = 'SOLD'
JOIN veh_mgmt_csr.rm_cust_mast
ON veh_mgmt_csr.cst_buyer_order.rm_cust_id = veh_mgmt_csr.rm_cust_mast.rm_cust_id
JOIN veh_mgmt_csr_rv.cst_address
ON veh_mgmt_csr.rm_cust_mast.prim_addr_id = veh_mgmt_csr_rv.cst_address.addr_id
AND veh_mgmt_csr_rv.cst_address.record_status = 'A'
LEFT JOIN
(
SELECT veh_mgmt_csr.cst_buyer_order.e_o_id cust_nbr,
Trim(veh_mgmt_csr.cst_individual.indiv_upp_frst_nam)
|| ' ' ||
Trim(veh_mgmt_csr.cst_individual.indiv_upp_last_nam) contact_name,
veh_mgmt_csr_rv.cst_phone_nbr.phn_nbr contact_phone
FROM veh_mgmt_csr.cst_e_o_cntct
LEFT JOIN veh_mgmt_csr.cst_individual
ON veh_mgmt_csr.cst_e_o_cntct.indiv_id = veh_mgmt_csr.cst_individual.indiv_id
LEFT JOIN veh_mgmt_csr_rv.cst_phone_nbr
ON veh_mgmt_csr.cst_e_o_cntct.indiv_id = veh_mgmt_csr_rv.cst_phone_nbr.indiv_id
AND veh_mgmt_csr_rv.cst_phone_nbr.prim_phn_ind = 1
qualify rank() OVER (partition BY veh_mgmt_csr.cst_e_o_cntct.e_o_id
ORDER BY contact_name ASC) = 1) e
ON veh_mgmt_csr.rm_cust_mast.rm_cust_id = e.cust_nbr
WHERE veh_mgmt_csr.cst_individual.veh_lgcy_nbr = '8B5RG1'
AND veh_mgmt_csr.cst_e_o_cntct.cntry_iso_cde IN ('US','CA')
AND extract(year FROM veh_mgmt_csr.cst_e_o_cntct.bo_dte) = 2017;
Per your update do the following:
To keep above Teradata syntax, create 2 pass-through queries (using same ODBC connection as linked tables) for each database.
Run same make-table query (SELECT * INTO myAccessTable FROM myTeradataPassThroughQuery) to move Teradata results into Access local tables.
Join the two new tables for your final end result using Access SQL syntax.
Related
I'm writing (in .NET) a login screen that allows the login to connect to a SQL Server. Once they've put in the server name and their credentials, it should then show a list of databases for them to connect to, but, the databases need to be of the right structure. This will be identified within each database by the existence of a ref.Config table, and a row in that table with appropriate values. There may be a whole bunch of other databases on the server for other purposes. I don't know at designtime.
Ideally what I'd like to do is something like this:
SELECT m.name
FROM MASTER.sys.databases m
CROSS APPLY (SELECT *
FROM {m.name}.INFORMATION_SCHEMA.TABLES t
WHERE t.TABLE_SCHEMA = 'ref'
AND t.TABLE_NAME 'Config') dbs
CROSS APPLY (SELECT *
FROM {m.name}.ref.Config c
WHERE c.KeyName = 'DatabaseMagicNumber'
AND c.KeyValue = '12345678') config
WHERE HAS_DBACCESS(m.name) = 1
ORDER BY m.name
Where m.name gets substituted into the subqueries after evaluation (I know the above isn't valid SQL). Is there a way to do this, or do I have to run a query on each database? I am unable to have a stored procedure on the server at this point. Ideally I just want one SQL statement that will return the names of all databases that conform to the structure I expect.
I am trying to recreate a query that was done in MS Access, and now is being handled in a SQL Server environment. I understand that some of the SQL syntax is different in Access than it is in SQL Server. Is there somewhere online that points out the main differences, or will help translate one to the other?
This is a query that I need to update to use in SQL Server:
UPDATE
dbo.TPR00100
INNER JOIN (
dbo.UPR10302
LEFT JOIN dbo.B3980280 ON dbo.TPR10302.COMPTRNM = dbo.B3980280.COMPTRNM
) ON dbo.TPR00100.STAFFID = dbo.TPR10302.STAFFID
SET
dbo.B3980280.COMPTRNM = dbo.TPR10302.comptrnm,
dbo.B3980280.BI_LOC_ID = dbo.TPR00100.locatnid
WHERE
(((dbo.B3980280.COMPTRNM) Is Null))
What are they key aspects that need to be handled differently in a SQL Server transaction for this query?
If find it handy to use an updateable CTE for this:
with cte as (
select
b39.comptrnm b39_comptrnm
b39.bssi_loc_id b39_bssi_loc_id,
tpr.comptrnm tpr_comptrnm,
tpr.locatnid tpr_locatnid
from dbo.tpr00100 tpr
inner join dbo.upr10302 upr on tpr.staffid = upr.staffid
inner join dbo.b3980280 b39 on tpr.comptrnm = b39.comptrnm
where b39_comptrnm is null
)
update cte
set b39_comptrnm = tpr_comptrnm, b39_bssi_loc_id = tpr_locatnid
Note: I am not really sure why the table to update is left joined in the original query, so I turned it to an `inner join .
I would like to JOIN 2 databases.
1 database is keyword_data (keyword mapping)
1 database is filled with Google rankings and other metrics
Somehow I cannot JOIN these two databases.
Some context:
DATA SET NAME: visibility
TABLE 1
keyword_data
VALUES
keyword
universe
category
search_volume
cpc
DATA SET NAME: visibility
TABLE 2
results
VALUES
Date
Keyword
Website
Position
In order to receive ranking data by date I wrote the following SQL line.
SELECT Date, Position, Website FROM `visibility.results` Keyword INNER
JOIN `visibility.keyword_data` keyword ON `visibility.results` Keyword
= `visibility.keyword_data` keyword GROUP BY Date;
(besides that, 100 other lines with no success ;-) )
I am using Google BigQuery for this with standard SQL (unchecked Legacy SQL).
How can I JOIN those 2 data tables?
How familiar are you with SQL? I think you're using aliases wrong, something like this should work
SELECT r.Date, r.Position, r.Website
FROM `visibility.results` AS r
INNER JOIN `visibility.keyword_data` AS k
ON r.Keyword = k.keyword
GROUP BY DATE
First of all i have never worked with Google big query but there is a couple of things wrong in my opinion with this query.
To start with you join tables by including the name of the table then you provide the key that the tables are joined by. Also if you don't use aggregate functions (MIN/MAX etc.) in your select statement you must include all values in the group by clause as well. In reference I can provide you a solution that would work if you would of used Microsoft SQL Server if that would be of any help because if you reference here the syntax is quite similar.
SELECT results.Date AS DATE,
,results.Position AS POSITION
,results.Website AS WEBSITE
FROM visibility.dbo.keyword_data AS keyword_data
INNER JOIN visibility.dbo.results AS results
ON results.keyword = keyword_data.keyword
GROUP BY results.Date
,results.Position
,results.Website
I am trying to convert a T-SQL query to MS Access SQL and getting a syntax error that I am struggling to find. My MS Access SQL query looks like this:
INSERT INTO IndvRFM_PreSort (CustNum, IndvID, IndvRScore, IndRecency, IndvFreq, IndvMonVal )
SELECT
IndvMast.CustNum, IndvMast.IndvID, IndvMast.IndvRScore,
IndvMast.IndRecency, IndvMast.IndvFreq, IndvMast.IndvMonVal
FROM
IndvMast
INNER JOIN
OHdrMast ON IndvMast.IndvID = OHdrMast.IndvID
INNER JOIN
MyParameterSettings on 1=1].ProdClass
INNER JOIN
[SalesTerritoryFilter_Check all that apply] ON IndvMast.SalesTerr = [SalesTerritoryFilter_Check all that apply].SalesTerr
WHERE
(((OHdrMast.OrdDate) >= [MyParameterSettings].[RFM_StartDate]))
GROUP BY
IndvMast.CustNum, IndvMast.IndvID, IndvMast.IndvRScore,
IndvMast.IndRecency, IndvMast.IndvFreq, IndvMast.IndvMonVal,
[CustTypeFilter_Check all that apply].IncludeInRFM,
[ProductClassFilter_Check all that apply].IncludeInRFM,
[SourceCodeFilter_Check all that apply].IncludeInRFM,
IndvMast.FlgDontUse
I have reviewed differences between MS Access SQL and T-SQL at http://rogersaccessblog.blogspot.com/2013/05/what-are-differences-between-access-sql.html and a few other locations but with no luck.
All help is appreciated.
update: I have removed many lines trying to find the syntax error and I am still getting the same error when running just (which runs fine using T-SQL):
SELECT
IndvMast.CustNum, IndvMast.IndvID, IndvMast.IndvRScore,
IndvMast.IndRecency, IndvMast.IndvFreq, IndvMast.IndvMonVal
FROM
IndvMast
INNER JOIN
OHdrMast ON IndvMast.IndvID = OHdrMast.IndvID
INNER JOIN
[My Parameter Settings] ON 1 = 1
There are a number of items in your query that should also have failed in any SQL-compliant database:
You have fields from tables in GROUP BY not referenced in FROM or JOIN clauses.
Number of fields in SELECT query do not match number of fields in INSERT INTO clause.
The MyParameterSettings table is not properly joined with valid ON expression.
Strictly MS Access SQL items:
For more than one join, MS Access SQL requires paired parentheses but even this can get tricky if some tables are joined together and their paired result joins to outer where you get nested joins.
Expressions like ON 1=1 must be used in WHERE clause and for cross join tables as MyParameterSettings appears to be, use comma-separated tables.
For above reasons and more, it is advised for beginners to this SQL dialect to use the Query Design builder providing table diagrams and links (if you have the MS Access GUI .exe of course). Then, once all tables connect graphically with at least one field selected, jump into SQL view for any nuanced scripting logic.
Below is an adjustment to SQL statement to demonstrate the parentheses pairings and for best practices, uses table aliases especially with long table names.
INSERT INTO IndvRFM_PreSort (CustNum, IndvID, IndvRScore, IndRecency, IndvFreq, IndvMonVal)
SELECT
i.CustNum, i.IndvID, i.IndvRScore, i.IndRecency, i.IndvFreq, i.IndvMonVal
FROM
[MyParameterSettings] p, (IndvMast i
INNER JOIN
OHdrMast o ON i.IndvID = o.IndvID)
INNER JOIN
[SalesTerritoryFilter_Check all that apply] s ON i.SalesTerr = s.SalesTerr
WHERE
(o.OrdDate >= p.[RFM_StartDate])
GROUP BY
i.CustNum, i.IndvID, i.IndvRScore, i.IndRecency, i.IndvFreq, i.IndvMonVal
And in your smaller SQL subset, the last table does not need an ON 1=1 condition and may be redundant as well in SQL Server. Simply a comma separate table will suffice if you intend for cross join. The same is done in above example:
SELECT
IndvMast.CustNum, IndvMast.IndvID, IndvMast.IndvRScore,
IndvMast.IndRecency, IndvMast.IndvFreq, IndvMast.IndvMonVal
FROM
[My Parameter Settings], IndvMast
INNER JOIN
OHdrMast ON IndvMast.IndvID = OHdrMast.IndvID
I suppose there are some errors in your query, the first (more important).
Why do you use HAVING clause to add these conditions?
HAVING (((IndvMast.IndRecency)>(date()-7200))
AND (([CustTypeFilter_Check all that apply].IncludeInRFM)=1)
AND (([ProductClassFilter_Check all that apply].IncludeInRFM)=1)
AND (([SourceCodeFilter_Check all that apply].IncludeInRFM)=1)
AND ((IndvMast.FlgDontUse) Is Null))
HAVING usually used about conditions on aggregate functions (COUNT, SUM, MAX, MIN, AVG), for scalar value you must put in WHERE clause.
The second: You have 12 parenthesis opened and 11 closed in HAVING clause
I'm REALLY new to SQL and I'm really struggling with all but the simplest of joins - especially in MS Access.
At this stage, all I want to do is create a query from two tables: 'tblUsers', with columns 'UserID' and 'User', and 'tblPayments' with columns 'PaymentID', 'User' and 'Authoriser'. I want my query to contain all of this data and also to have columns 'UserID' and 'AuthoriserID', both of these ID numbers being taken from 'tblUsers', but clearly one will relate to the User and one to the authoriser.
I'm sure this is far more simple than I'm making it but how should I do this?
Thanks in advance.
Keep in mind that there are minor differences in syntax between SQL server SQL and Access SQL. While in most cases a query written in Access will function normally on SQL server, the opposite is less true because of the shortcuts often used on SQL server (example: dropping the 'INNER' from the joins and the 'AS' when using an alias.)
Access:
SELECT tblUsers.UserID,
tblUsers.User,
tblPayments.paymentID,
tblUsers.User AS Authoriser,
tblUsers_1.UserID AS AuthoriserID
FROM (tblPayments
INNER JOIN tblUsers AS tblUsers_1
ON tblPayments.AuthorisorID = tblUsers_1.UserID)
INNER JOIN tblUsers
ON tblPayments.userID = tblUsers.UserID;
SQL Server:
SELECT tblUsers.UserID,
tblUsers.User,
tblPayments.paymentID,
tblUsers.User Authoriser,
tblUsers_1.UserID AuthoriserID
FROM tblPayments
JOIN tblUsers tblUsers_1
ON tblPayments.AuthorisorID = tblUsers_1.UserID
JOIN tblUsers
ON tblPayments.userID = tblUsers.UserID;