Syntax error(missing operator) in query expression in MSAccess - database

I have written a query in MS Access when i am trying to run this query i am getting an error. I can't find out the problem in it.
SELECT
p.[ID] as [ID],
p.[Code] as [CODE],
p.[DESCRIPTION] as [DESCRIPTION],
p.[Coloring] as [Coloring],
p.[Sizing] as [Sizing],
p.[BarCode] as [Barcode],
p.[PartsNo] as [PartsNo],
p.[HSN_SAC] as [HSN_SAC],
p.[GSTRate] as [GSTRate],
p.[Remarks] as Remarks,
c.[CODE] as [CategoryCode],
c.[Description] as [CategoryDescription],
b.[CODE] as [BrandCode],
b.[Description] as [BrandDescription],
s.[Id] as [SupplierId],
s.[Code] as [SupplierCode],
s.[Description] as [SupplierDescription]
FROM [PRODUCTMASTER] p LEFT JOIN [CATEGORYMASTER] c on p.[CategoryId] = c.[ID]
LEFT JOIN [BRANDMASTER ] b on p.[BrandId] = b.[ID]
LEFT JOIN [SUPPLIERAMSTER] s on p.[SupplierId] = s.[ID]

When you linking more than two tables, brackets required:
FROM (([PRODUCTMASTER] p LEFT JOIN [CATEGORYMASTER] c on p.[CategoryId] = c.[ID])
LEFT JOIN [BRANDMASTER ] b on p.[BrandId] = b.[ID])
LEFT JOIN [SUPPLIERAMSTER] s on p.[SupplierId] = s.[ID]
I would recommend to build SQL queries using query builer, it's much easier than manually and you won't have misspelling and bracketing errors like this. Check one more time for the space after [BRANDMASTER ], this is bad practice in any case. Remove trailing space from column name in table definition, it may cause other weird errors.

Related

IS NULL being ignored

I am trying to run a query in T-SQL to pull back a data set based on a column being null.
This is a simplified version of the code:
SELECT
T1.Col1, T1.Col2,
T1.Col3, T1.Col4
FROM
table1 AS T1
INNER JOIN
table2 AS T2 ON T1.Col2 = T2.Col3
WHERE
T2.Col4 IS NULL
Problem is, the result includes rows where T2.Col4 are NULL and also not NULL, it's like the WHERE clause doesn't exist.
Any ideas would be greatly
UPDATE - full version of code:
SELECT
M.ref
,C.cname
,CL.clname
,C.ccity
,M.productLine
,M.code
,CL.date
,M.dept
,DPT.group
,TK2.tkname
,TK2.tkdept
FROM DB.dbo.manage AS M
OUTER JOIN DB.dbo.ClientManageRelationship AS CMR
ON CMR.RelatedEntityID = M.EntityID
OUTER JOIN DB.dbo.Client AS C
ON C.EntityID = CMR.EntityID
INNER JOIN DB.dbo.ManageCustomerRelationship AS MCR
ON MCR.EntityID = M.EntityID
INNER JOIN DB.dbo.Customer AS CL
ON CL.EntityID = MCR.RelatedID
INNER JOIN DB.dbo.timek AS TK
ON TK.tki = M.tkid
LEFT JOIN (SELECT Group = division, [Department] = newdesc, deptcode FROM DB.csrt.vw_rep_p_l_dept) AS DPT
ON tkdept = DPT.dept
LEFT JOIN (SELECT Name = TK2.tkfirst + ' ' + TK2.tklast, TK2.tki, TK2.dept, TK2.loc FROM DB.dbo.timek as TK2 WITH(NOLOCK)) AS TK2
ON TK2.tki = M.tkid
WHERE DPT.Department = 'Casualty'
AND UPPER (C.ClientName) LIKE '%LIMITED%'
AND CL.date > '31/12/2014'
AND CL.Date IS NULL
AND TK.tkloc = 'loc1' OR TK.tkloc = 'loc2'
ORDER BY M.ref
My first answer would be because you're using INNER JOIN. This only returns matches between the 2 tables. TRY FULL OUTER JOIN which will return all values regardless of matches and will include NULLS.
If you were looking to return all rows regardless of matches including NULLS from only one of the tables then use RIGHT or LEFT JOIN.
Say i had 2 tables ('Person' and 'Figure'). Not every person may have entered a figure on any one day. But an example may be i want to return all people regardless of whether they entered a figure or not on a certain day.
My initial approach to this would be a LEFT join because i want to return of all the people(left table) regardless of there being any matches in the figure table(right table)
FROM Person P
LEFT JOIN Figure F
ON P.ID = F.ID
This would produce a result such as
Name Figure
Sam 20
Ben 30
Matt NULL
Simon NULL
Whereas,
An inner join would produce only matching values not including nulls
Name Figure
Sam 20
Ben 30
Left join works the same way as right join but in the opposite direction. This is most likely the problem you were facing. But i hope this helped
I think the problem is in the last part of the where condition.
You should use brackets.
`WHERE DPT.Department = 'Casualty'
AND UPPER (C.ClientName) LIKE '%LIMITED%'
AND CL.date > '31/12/2014'
AND CL.Date IS NULL
AND (TK.tkloc = 'loc1' OR TK.tkloc = 'loc2')`
or
`WHERE DPT.Department = 'Casualty'
AND UPPER (C.ClientName) LIKE '%LIMITED%'
AND CL.date > '31/12/2014'
AND CL.Date IS NULL
AND TK.tkloc IN ('loc1', 'loc2')`

SQL joining same columns in different ways

select top 1000
f.*, s.TimeZoneCode as TimeZoneOrigin,
s2.TimeZoneCode as TimeZoneDestination,
tz.StandardVariation as VariationOrigin,
tz2.StandardVariation as VariationDestination,
tzv.Variation as TimeVariation,
tzv2.Variation as TimeVariation2
from
REZNVWB01.MIT.HVResearchDataSetDraft1 f
inner join
REZNVOD01.dbo.Station s on s.StationCode = f.TripOriginLocationCode
inner join
REZNVOD01.dbo.Station s2 on s2.StationCode = f.TripDestinationLocationCode
inner join
REZNVOD01.dbo.TimeZone tz on tz.TimeZoneCode = s.TimeZoneCode
inner join
REZNVOD01.dbo.TimeZone tz2 on tz2.TimeZoneCode = s.TimeZoneCode
inner join
REZNVOD01.dbo.TimeZoneVariation tzv on tzv.TimeZoneCode = s.TimeZoneCode
and tzv.EndUTC >= BookingDate
and tzv.StartUTC <= BookingDate
I have one table with StartUTC and EndUTC and timezonevariation for each row. I want to look at BookingTime, and gain the timezonevariation for when bookingtime is between StartUTC and EndUTC.
What do I need to change in this code?
inner join
REZNVOD01.dbo.TimeZoneVariation tzv on tzv.TimeZoneCode = s.TimeZoneCode
and tzv.EndUTC >= BookingDate
and tzv.StartUTC <= BookingDate
Is this code correct if the TimeZoneVariation code StartUTC and EndUTC are between conditions (IE startUTC might be 5:00 and endUTC might be 10:00, I want the TimeZoneVariation value where BookingDate is between startUTC and endUTC)
To answer your first question - merely by the logic - you can use the BETWEEN statement that could make your intent clearer. BETWEEN is inclusive, which means it includes the values at either end of the range in the comparison:
INNER JOIN REZNVOD01.dbo.TimeZoneVariation tzv
ON tzv.TimeZoneCode = s.TimeZoneCode AND
BookingDate BETWEEN tzv.EndUTC AND tzv.StartUTC
However, you're not clarifying whether "BookingDate" is a field within "f" or a variable. If it's a variable, make sure you prepend it with the commercial at (#) and if it's from "f", please declare it as such (E.G. f.BookingDate). This practice will make your code clearer to those reading it.
As to your final query ... it might be beneficial to spell out your table aliases instead of abbreviating them so much (I like to break my lines down and do indentation to help visualize the join relationships):
SELECT TOP 1000
f.*,
origStation.TimeZoneCode AS TimeZoneOrigin,
destStation.TimeZoneCode AS TimeZoneDestination,
origTz.StandardVariation AS VariationOrigin,
destTz.StandardVariation AS VariationDestination,
origTzv.Variation AS TimeVariationOrigin,
destTzv.Variation AS TimeVariationDestination
FROM
REZNVWB01.MIT.HVResearchDataSetDraft1 AS f
INNER JOIN REZNVOD01.dbo.Station AS origStation
ON origStation.StationCode=f.TripOriginLocationCode
INNER JOIN REZNVOD01.dbo.Station AS destStation
ON destStation.StationCode=f.TripDestinationLocationCode
INNER JOIN REZNVOD01.dbo.TimeZone AS origTz
ON origTz.TimeZoneCode=origStation.TimeZoneCode
INNER JOIN REZNVOD01.dbo.TimeZone AS destTz
ON destTz.TimeZoneCode=destStation.TimeZoneCode
INNER JOIN REZNVOD01.dbo.TimeZoneVariation AS origTzv
ON origTzv.TimeZoneCode = origStation.TimeZoneCode AND
f.BookingDate BETWEEN origTzv.EndUTC AND origTzv.StartUTC
INNER JOIN REZNVOD01.dbo.TimeZoneVariation AS destTzv
ON destTzv.TimeZoneCode = destStation.TimeZoneCode AND
f.BookingDate BETWEEN destTzv.EndUTC AND destTzv.StartUTC
I don't quite understand your last question. Could you please restate it?
Thanks!

oracle grammar to h2 grammar (+) join table

I have the following query as Oracle
SELECT DISTINCT count(pa.payment_id) FROM
location c, inventory e,
inventory_stock es, payment_client ep,
payment pa, currency cur,
location s, exchange_country exc,
exchange_rate sso,
exchange_hike so,
exchange_margin sov WHERE
cur.outState = 'N' AND
c.location_id = e.location_id AND
e.inventory_id = ep.inventory_id AND
e.inventory_stock_id = es.inventory_stock_id AND
ep.client_id = pa.end_client AND
pa.cur_id = cur.cur_id AND
cur.location_id = s.location_id AND
c.client_id is not null AND
cur.cur_id = exc.cur_id(+) AND
exc.exchange_id = sso.exchange_id(+) AND
sso.account_id = so.account_id(+) AND
so.option_name(+) = 'PREMIUM' AND
exc.exchange_id = sov.exchange_id(+) AND
sov.name(+) = 'VALUE';
Right now I am using H2 database and the syntax error I got was from so.option_name(+) and sov.name(+); I know the (+) are oracle's way of right join and left join but are there any possible way to convert this into h2 so the error and the grammar are equivalent?
It's time to move on. Oracle's legacy outer join syntax is no longer recommended by Oracle. From the docs:
Oracle recommends that you use the FROM clause OUTER JOIN syntax rather than the Oracle join operator. Outer join queries that use the Oracle join operator (+) are subject to the following rules and restrictions, which do not apply to the FROM clause OUTER JOIN syntax [...]
If you replace (+) usage by outer join, not only will your query work on both Oracle and H2, it will also be an important step forward for your application as a whole.
SELECT DISTINCT count(pa.payment_id)
FROM location c
JOIN inventory e ON c.location_id = e.location_id
JOIN payment_client ep ON e.inventory_id = ep.inventory_id
JOIN inventory_stock es ON e.inventory_stock_id = es.inventory_stock_id
JOIN payment pa ON ep.client_id = pa.end_client
JOIN currency cur ON pa.cur_id = cur.cur_id
JOIN location s ON cur.location_id = s.location_id
LEFT JOIN exchange_country exc ON cur.cur_id = exc.cur_id
LEFT JOIN exchange_rate sso ON exc.exchange_id = sso.exchange_id
LEFT JOIN exchange_hike so
ON sso.account_id = so.account_id
AND so.option_name = 'PREMIUM'
LEFT JOIN exchange_margin sov
ON exc.exchange_id = sov.exchange_id
AND sov.name = 'VALUE'
WHERE c.client_id IS NOT NULL
AND cur.outState = 'N'
The importance when converting from (+) to LEFT JOIN is that you pay close attention which predicates must go into an ON clause, and which predicates are fine in the WHERE clause. In particular, the following two predicates must go in the relevant left joined table's ON clause:
so.option_name(+) = 'PREMIUM'
sov.name(+) = 'VALUE'
Third party tooling
You can use jOOQ's online SQL translator to translate between the syntaxes, or use jOOQ directly to translate from table lists with Oracle joins to ansi joins.
Disclaimer: I work for the company behind jOOQ

Referencing Results of Multiple Temporary Tables in SQL Server

I’m using SQL Server 2008
I have joins written something like the following, where the first join is encapsulated in a ‘With as’ statement so that I can name the output table as ‘A’ and then reference the ‘A’ resulting table in the next select and Join seen beneath it.
This works perfectly fine. What I would like to do then is reference that second table for another select statement and join, but when I try to wrap it in a ‘With as’ statement as well, the editor does not accept it as legitimate syntax for the second instance of 'With as'.
How can I subset resulting tables to reference in further select and join statements? I do not have permission to write to the database, so I can not create permanent tables in the database.
Thank you.
With A as
(
SELECT POL.[COMPANY_CODE]
,POL.[POLICY_NUMBER]
,POL.[STATUS_CODE]
,POL.ORIG_CLIENT_NUM
,TA.LINE
FROM [SamsReporting].[dbo].[POLICY] POL
Left join [SamsReporting].[dbo].[Transact] TA
ON TA.POLICY_NUMBER = POL.POLICY_NUMBER and TA.BASE_Account = 'B'
)
Select PM.POLICY_NUMBER
,A.[COMPANY_CODE]
,A.[POLICY_NUMBER]
,A.[Policy Status]
,eApp.SourceCode
From A
Left Join Web.dbo.Pmetrics PM on A.POLICY_NUMBER=PM.POLICY_NUMBER
Left Outer Join DDP.pol.eAppStaging eApp
on A.POLICY_NUMBER=eApp.PolicyNumber
where eApp.SourceCode = 'HAQ' or eApp.SourceCode = 'PLS'
Common Table Expressions (CTEs) can build upon each other as you would like. For example, you can do this:
WITH CTE1 AS (SELECT * FROM Table 1)
, CTE2 AS (SELECT * FROM CTE1)
, CTE3 AS (SELECT * FROM CTE2)
You only need the WITH statement for the first CTE. After that just use the CTE name, as in my example.
Hope that helps,
Ash
Sounds like a syntax issue to me. Google CTE (Common Table Expression) and review some examples of how they are formed.
With A as
(SELECT POL.[COMPANY_CODE]
,POL.[POLICY_NUMBER]
,POL.[STATUS_CODE]
,POL.ORIG_CLIENT_NUM
,TA.LINE
FROM [SamsReporting].[dbo].[POLICY] POL
Left join [SamsReporting].[dbo].[Transact] TA
ON TA.POLICY_NUMBER = POL.POLICY_NUMBER and TA.BASE_Account = 'B'),
B as (
Select PM.POLICY_NUMBER
,A.[COMPANY_CODE]
,A.[POLICY_NUMBER]
,A.[Policy Status]
,eApp.SourceCode
From A
Left Join Web.dbo.Pmetrics PM on A.POLICY_NUMBER=PM.POLICY_NUMBER
Left Outer Join DDP.pol.eAppStaging eApp
on A.POLICY_NUMBER=eApp.PolicyNumber
where eApp.SourceCode = 'HAQ' or eApp.SourceCode = 'PLS')
Select *
From B -- inner join some table
where some condition = 1

Query Optimizer can't push predicate past rollup? HINTs doesn't work also

This is the schema :
And this is the sql that as I understand is too complex for SQL Optimizer:
SELECT * FROM
(
select pp.Id as PaymentPartId, b.Id as BudgetId, grouping(bp.ID) as g1 , sum(pp.Amount) PaymentsSum, sum(bp.Amount) BudgetSum
from Projects pr
inner join Payments p ON pr.Id = p.ProjectID
inner join PaymentParts pp ON p.Id = pp.PaymentId
inner join Budgets b ON pr.Id = b.ProjectID
inner join Budgetparts bp ON b.Id = bp.BudgetId
group by pp.Id, b.Id, rollup(bp.ID)
) x
WHERE x.PaymentPartId = 777
SQLFIDDLE: http://sqlfiddle.com/#!6/aa74e/11 (with autogenerated data)
What I expect: execution plan should contain index seek on x.PaymentPartId. Why? Because this query is equivalent to:
select pp.Id as PaymentPartId, b.Id as BudgetId, grouping(bp.ID) as g1, sum(pp.Amount) PaymentsSum, sum(bp.Amount) BudgetSum
from Projects pr
inner join Payments p ON pr.Id = p.ProjectID
inner join PaymentParts pp ON p.Id = pp.PaymentId
inner join Budgets b ON pr.Id = b.ProjectID
inner join Budgetparts bp ON b.Id = bp.BudgetId
WHERE pp.Id = 777
group by pp.Id, b.Id, rollup(bp.ID)
...and the last query uses index seek.
But SQL Optimizer not only refuse to use the index but ignore all hints (I propose you to expirement wiht sqlfiddle - it is really interesting).
So the question is: am I right that it is impossible to force SQL Server Optimizer to use index seek there? It seems like rollup is something that split sql optimizer "optimization frame" to two parts and it makes it impossible to optimize WHOLE query.
P.S. For those who votes for closing this "non-programming question": try to put optimizer hints (sqlfiddle is ready to test your programming skills!).
Why hints doesn't work? - Roman Pokrovskij
It is in the documentation:
http://technet.microsoft.com/en-us/library/ms181714.aspx
Query hints can be specified only in the top-level query, not in subqueries

Resources