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
Related
Good mroning SO. I'm working on an over-normalized DB running off a program that we didn't build in house. We need to pull data from different tables to make it work. When I run the following query, it results in:
Msg 4104, Level 16, State 1, Line 14 The multi-part identifier
"dbo.db_record.db_record_id" could not be bound.
I have looked into this, and I cannot find a reason for the error, and am trying to figure out what I can possibly do to fix this.
USE [Acuity_Train]
select p.provider_identity,
p.provider_type,
p.provider_name,
p.NPI,
t.taxonomy_code,
udf.user_field_data_09 AS [Medicaid #]
from provider p
--This join links provider data to taxonomy table for taxonomy code select above
LEFT OUTER JOIN dbo.provider_taxonomy prvt
ON prvt.provider_identity = p.provider_identity
INNER JOIN dbo.taxonomy t
ON t.taxonomy_identity = prvt.taxonomy_identity
-- This allows for access to medicaid ID #
LEFT OUTER JOIN v_provider_network_affiliation vpna
ON vpna.key2 = p.provider_identity
AND vpna.key1 in ('55', '56')
LEFT OUTER JOIN user_field_data AS udf
ON udf.table_code='PRNW'
AND udf.key1=vpna.provider_affiliation_identity
-- Next 3 Joins needed to access company.company_code
LEFT OUTER JOIN dbo.provider_affiliation praf
ON praf.db_record_id_child = dbo.db_record.db_record_id
LEFT OUTER JOIN dbo.db_record AS dbr_parent
ON praf.db_record_id_parent = dbr_parent.db_record_id
LEFT OUTER JOIN company
ON dbr_parent.key1 = company.company_identity
Where company.company_code in ('Prestige', '114', '115', '148', '181')
Where you have...
LEFT OUTER JOIN dbo.provider_affiliation praf
ON praf.db_record_id_child = dbo.db_record.db_record_id
You have at that point not introduced dbo.db_record so it has no idea what you want to join to.
Missed a join step, needed to hit another table on the way here.
LEFT OUTER JOIN dbo.db_record
ON p.provider_identity = dbo.db_record.key1
AND dbo.db_record.table_code = 'PROV'
LEFT OUTER JOIN dbo.provider_affiliation praf
ON praf.db_record_id_child = dbo.db_record.db_record_id
LEFT OUTER JOIN dbo.db_record AS dbr_parent
ON praf.db_record_id_parent = dbr_parent.db_record_id
LEFT OUTER JOIN company
ON dbr_parent.key1 = company.company_identity
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.
My query is not joining the three tables in SQL Server.
Code:
SELECT Ledger.ledger_id,
Ledger.std_reg_id,
Ledger.fee_of_month,
Ledger.ledger_date,
Ledger.fees,
Other_Fees.other_fees_id,
Other_Fees.title
FROM Ledger
INNER JOIN Other_Fees
ON Ledger.other_fees_id = Other_Fees.other_fees_id
INNER JOIN Std_Profile
ON Ledger.std_reg_id = Std_Profile.std_reg_id
An INNER JOIN will only return records that match in both tables. It's possible that between the 3 tables, there's no identically matching data. Try using a LEFT JOIN and see if it returns anything. By using a LEFT JOIN, you should at least get everything back from dbo.Ledger.
Also, you should probably alias your tables like such:
SELECT
L.ledger_id,
L.std_reg_id,
L.fee_of_month,
L.ledger_date,
L.fees,
F.other_fees_id,
F.title
FROM dbo.Ledger L
LEFT JOIN dbo.Other_Fees F
ON L.other_fees_id = F.other_fees_id
LEFT JOIN dbo.Std_Profile P
ON L.std_reg_id = P.std_reg_id
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
I have a database assignment which I have to create some relational algebra for two problems. I feel fairly all right with the majority of it, but I just get confused when trying to project attributes out of a table which is joined to another table.
for example is this correct?
Q1) List the details of incidences with no calls made, so that the receptionist knows
which incidents still need to be called in.
RESULT <-- PROJECT<STUDENT.FirstName, STUDENT.LastName, STAFF.FirstName,
STAFF.INCIDENT.LastName, INCIDENT.DateTimeReported,
INCIDENT.NatureOfIllness(SELECTINCIDENT.DecisionMade =
''(Staff RIGHT JOIN<STAFF.StaffID = INCIDENT.StaffID>
(INCIDENT LEFT JOIN<INCIDENT.StudentID = STUDENT.StudentID>(STUDENT))))
The SQL which I am trying to interpret into relational algebra is:
SELECT
s.FirstName, s.LastName, st.FirstName, st.LastName
, i.DateTimeReported, i.NatureOfIllness
FROM Student s
RIGHT JOIN Incident i ON s.StudentID = i.StudentID
LEFT JOIN Staff st ON st.StaffID = i.StaffID
WHERE i.DecisionMade = ''
Any points of advice would be much appreciated.
It's usually (some exceptions apply, of course) easier to read and understand the sql if you write it all with LEFT JOINs:
SELECT s.FirstName, s.LastName, st.FirstName, st.LastName, i.DateTimeReported, i.NatureOfIllness
FROM Incident i
LEFT JOIN Student s ON s.StudentID = i.StudentID
LEFT JOIN Staff st ON st.StaffID = i.StaffID
WHERE i.DecisionMade = ''
Your version seems correct, except for some typos like STAFF.INCIDENT.LastName. Here's my version:
RESULT <---
PROJECT <STUDENT.FirstName, STUDENT.LastName,
STAFF.FirstName, STAFF.LastName,
INCIDENT.DateTimeReported, INCIDENT.NatureOfIllness>
(SELECT <INCIDENT.DecisionMade = ''>
((STUDENT RIGHT JOIN <STUDENT.StudentID = INCIDENT.StudentID> INCIDENT)
LEFT JOIN <INCIDENT.StaffID = STAFF.StaffID> STAFF)