I have two tables: One is InvWarehouse which contains most of the data. The other is InvMaster+ which contains what I'm filtering on (Which is SalesDemandClass).
How do I join these in an update statement?
Here's what I have so far, but it doesn't work. I tried to connect them on StockCode (which is in both), but if I put InvWarehouse A it says it expects the SET to be there instead.
update InvWarehouse A
set MinimumQty = SafetyStockQty, MaximumQty = (SafetyStockQty * 3)
from InvWarehouse
left join [InvMaster+] B on A.StockCode = B.StockCode
where SalesDemandClass in ('D4','D8','D12')
Making the assumption from the square bracket delimiters this is SQL Server, you need the correct syntax:
update iw set
iw.MinimumQty = im.SafetyStockQty,
iw.MaximumQty = SafetyStockQty * 3
from InvWarehouse iw
left join [InvMaster+] im on im.StockCode = iw.StockCode
where iw.SalesDemandClass in ('D4','D8','D12');
Try to get in the good habit of using meaningful table aliases and using them for all columns to avoid you and others guessing.
Related
I'm currently trying to draw multiple tables through several inner-join statements. However, I am continually hit with the following error:
ORA-00904: "PART"."ITEM_CLASS": invalid identifier
I've visited several other pages here but that problem did not coincide with mine.
Here is the SQL query:
SELECT Slsrep_Number, AVG(Commission_Rate) AS AVG_Rate, MAX(Total_Commission) as MAX_Comission
FROM Sales_Rep
WHERE Sales_Rep.Slsrep_Number = Customer.Slrsrep_Number
AND Customer.C_Number = Orders.C_Number
AND Orders.Order_Number = Order_Line.Order_Number
AND Order_Line.Part_Number = Part.Part_Number
AND Part.Item_Class = 'SG';
Here are the tables being used (screenshots):
The pictures are listed in the order that I am referencing them in the SQL query.
You need to reference the tables in the FROM clause. You can't just reference them.
You should also use table aliases and proper, explicit, standard JOIN syntax.
So:
SELECT sr.Slsrep_Number,
AVG(?.Commission_Rate) AS AVG_Rate,
MAX(?Total_Commission) as MAX_Comission
FROM Sales_Rep sr JOIN
Customer c
ON sr.Slsrep_Number = c.Slrsrep_Number JOIN
Orders o
ON c.C_Number = o.C_Number JOIN
Order_Line ol
ON o.Order_Number = ol.Order_Number
Part p
ON ol.Part_Number = p.Part_Number
WHERE p.Item_Class = 'SG';
The ? is for the alias for the column with the commission.
The query now "looks" right. However, I don't think it is particularly useful. If that is the case, ask another question and provide sample data, desired results, and an explanation of what you want to accomplish.
Customer,Orders,Order_Line and Part Tables are missing in the from clause.Try This.
SELECT Slsrep_Number,
AVG(Commission_Rate) AS AVG_Rate,
MAX(Total_Commission) as MAX_Comission
FROM Sales_Rep,Customer,Orders,Order_Line,Part
WHERE Sales_Rep.Slsrep_Number = Customer.Slrsrep_Number
AND Customer.C_Number = Orders.C_Number
AND Orders.Order_Number = Order_Line.Order_Number
AND Order_Line.Part_Number = Part.Part_Number
AND Part.Item_Class = 'SG';
I am having a rows with two different IDs in database. Now I am trying to show two different data columns in one row, I tried something like this:
SELECT
[dbo].[fnHexToNumber]([Participant].[Stake]) AS [PlayerStake],
(SELECT [dbo].[fnHexToNumber]([Stake])
FROM [dbo].[Participant_Complete]
WHERE [ParticipantId] = [Fold].[HouseParticipantId]) AS [HouseStake],
([dbo].[fnHexToNumber]([Participant].[Stake]) + [dbo].[fnHexToNumber]([C].[RunningWinLoss])) AS [PlayerStakeAfterRound],
(SELECT [dbo].[fnHexToNumber]([Stake])
FROM [dbo].[Participant_Complete]
WHERE [ParticipantId] = [Fold].[HouseParticipantId]) - [dbo].[fnHexToNumber]([C].[RunningWinLoss]) AS [HouseStakeAfterRound]
FROM
[dbo].[Round_Complete] AS [C]
INNER JOIN
[dbo].[Fold_Complete] AS [Fold] ON [Fold].[Id] = [C].[Id]
INNER JOIN
[dbo].[Participant_Complete] AS [Participant] ON [Participant].[ParticipantId] = [Fold].[PlayerParticipantId]
This works, but as you can see it will do two trips to database for same nested select. How can I make this only one round trip?
You are referring to the subqueries. That is not a "round trip to the database", which usually refers to an application calling a query.
All the square braces make the query hard to read, but you can fix this using apply:
SELECT [dbo].[fnHexToNumber](p.[Stake]) AS PlayerStake,
h.HouseStake,
([dbo].[fnHexToNumber](p.[Stake]) + [dbo].[fnHexToNumber]([C].RunningWinLoss)) AS PlayerStakeAfterRound,
(h.HouseStake - [dbo].fnHexToNumber(C.RunningWinLoss)) AS HouseStakeAfterRound
FROM [dbo].[Round_Complete] c JOIN
[dbo].[Fold_Complete] f
ON f.[Id] = c.[Id] JOIN
[dbo].[Participant_Complete] pc
ON px.[ParticipantId] = f.[PlayerParticipantId] OUTER APPLY
(SELECT [dbo].[fnHexToNumber]([Stake]) as HouseStake
FROM [dbo].[Participant_Complete] pch
WHERE pch.ParticipantId = f.HouseParticipantId
) h
Just join the same table a second time instead of pulling the data as sub-queries.
Also, you only need brackets around names if the names contain a space (which is bad practice in general). If the names don't have a space, the brackets are totally extraneous.
SELECT
dbo.fnHexToNumber(Participant.Stake) AS PlayerStake,
dbo.fnHexToNumber(p.Stake) as HouseStake,
(dbo.fnHexToNumber(Participant.Stake) + dbo.fnHexToNumber(C.RunningWinLoss)) AS PlayerStakeAfterRound,
dbo.fnHexToNumber(p.Stake) - dbo.fnHexToNumber(c.RunningWinLoss) as HouseStakeAfterRound
FROM dbo.Round_Complete AS C
INNER JOIN dbo.Fold_Complete AS Fold
ON Fold.Id = C.Id
INNER JOIN dbo.Participant_Complete AS Participant
ON Participant.ParticipantId = Fold.PlayerParticipantId
INNER JOIN dbo.Participant_Complete AS p
ON p.ParticipantId = Fold.HouseParticipantId
I'm working with MS Access, trying to join 3 tables together. But i'm getting message "JOIN EXPRESSION NOT SUPPORTED.".
Basically I want to join just 2 tables which are A_01HWeekEHCalendar and A00_Plant. A00_Plant requires 3 column to join; Plant_Product, Plant_Code, and Plant_Name. Plant_Product, Plant_Code is ok, but there is no column to match Plant_Product. so I have to add A_ProductGroup
I'm not sure if it can't be done in one Query or it's error from my SYNTAX. or there will be another way to do that without separate Queries.
I also add a picture of what I want and try to run and get error.
Thanks.
SELECT
A_01HWeekEHCalendar.RunNo_H,
A_01HWeekEHCalendar.Audit_Week,
A_01HWeekEHCalendar.CurrentYear,
A_01HWeekEHCalendar.CurrentWeek,
A_01HWeekEHCalendar.TTSMonth,
A_01HWeekEHCalendar.Audit_Plant,
A_01HWeekEHCalendar.Audit_plantname,
A_01HWeekEHCalendar.Audit_Qacode,
A_01HWeekEHCalendar.Audit_Qaname,
A_01HWeekEHCalendar.Audit_Product,
A00_Plant.HCA_StartDate
FROM
(A_01HWeekEHCalendar LEFT JOIN A_ProductGroup
ON A_01HWeekEHCalendar.Audit_Product = A_ProductGroup.R_Code)
LEFT JOIN A00_Plant
ON A_01HWeekEHCalendar.Audit_plantname = A00_Plant.Plant_Name
AND A_01HWeekEHCalendar.Audit_Plant = A00_Plant.Plant_Code
AND A_ProductGroup.R_Code = A00_Plant.Plant_Product;
You are lucky because you want only one column. You can work around this problem using a correlated subquery:
SELECT . . .,
(SELECT TOP (1) A00_Plant.HCA_StartDate
FROM A00_Plant
WHERE A_01HWeekEHCalendar.Audit_plantname = A00_Plant.Plant_Name
AND
A_01HWeekEHCalendar.Audit_Plant = A00_Plant.Plant_Code AND
A_ProductGroup.R_Code = A00_Plant.Plant_Product
) as HCA_StartDate
FROM A_01HWeekEHCalendar LEFT JOIN
A_ProductGroup
ON A_01HWeekEHCalendar.Audit_Product = A_ProductGroup.R_Code ;
I'm trying to retrieve a list of components via my computer_system, BUT if a computer system's graphics card is set to null (I.e. It has an onboard), the row isn't returned by my select statement.
I've been trying to use COALESCE without results. I've also tried with and OR in my WHERE clause, which then just returns my computer system with all different kinds of graphic cards.
Relevant code:
SELECT
computer_system.cs_id,
computer_system.cs_name,
motherboard.name,
motherboard.price,
cpu.name,
cpu.price,
gfx.name,
gfx.price
FROM
public.computer_case ,
public.computer_system,
public.cpu,
public.gfx,
public.motherboard,
public.ram
WHERE
computer_system.cs_ram = ram.ram_id AND
computer_system.cs_cpu = cpu.cpu_id AND
computer_system.cs_mb = motherboard.mb_id AND
computer_system.cs_case = computer_case.case_id AND
computer_system.cs_gfx = gfx.gfx_id; <-- ( OR computer_system.cs_gfx IS NULL)
Returns:
1;"Computer1";"Fractal Design"; 721.00; "MSI Z87"; 982.00; "Core i7 I7-4770K "; 2147.00; "Crucial Gamer"; 1253.00; "ASUS GTX780";3328.00
Should I use Joins? Is there no easy way to say return the requested row, even if there's a bloody NULL value. Been struggling with this for at least 2 hours.
Tables will be posted if needed.
EDIT: It should return a second row:
2;"Computer2";"Fractal Design"; 721.00; "MSI Z87"; 982.00; "Core i7 I7-4770K "; 2147.00; "Crucial Gamer"; 1253.00; "null/nothing";null/nothing
You want a LEFT OUTER JOIN.
First, clean up your code so you use ANSI joins so it's readable:
SELECT
computer_system.cs_id,
computer_system.cs_name,
motherboard.name,
motherboard.price,
cpu.name,
cpu.price,
gfx.name,
gfx.price
FROM
public.computer_system
INNER JOIN public.computer_case ON computer_system.cs_case = computer_case.case_id
INNER JOIN public.cpu ON computer_system.cs_cpu = cpu.cpu_id
INNER JOIN public.gfx ON computer_system.cs_gfx = gfx.gfx_id
INNER JOIN public.motherboard ON computer_system.cs_mb = motherboard.mb_id
INNER JOIN public.ram ON computer_system.cs_ram = ram.ram_id;
Then change the INNER JOIN on public.gfx to a LEFT OUTER JOIN:
LEFT OUTER JOIN public.gfx ON computer_system.cs_gfx = gfx.gfx_id
See PostgreSQL tutorial - joins.
I very strongly recommend reading an introductory tutorial to SQL - at least the PostgreSQL tutorial, preferably some more material as well.
It looks like it's just a bracket placement issue. Pull the null check and the graphics card id comparison into a clause by itself.
...
computer_system.cs_case = computer_case.case_id AND
(computer_system.cs_gfx IS NULL OR computer_system.cs_gfx = gfx.gfx_id)
Additionally, you ask if you should use joins. You are in fact using joins, by virtue of having multiple tables in your FROM clause and specifying the join criteria in the WHERE clause. Changing this to use the JOIN ON syntax might be a little easier to read:
FROM sometable A
JOIN someothertable B
ON A.somefield = B.somefield
JOIN somethirdtable C
ON A.somefield = C.somefield
etc
Edit:
You also likely want to make the join where you expect the null value to be a left outer join:
SELECT * FROM
first_table a
LEFT OUTER JOIN second_table b
ON a.someValue = b.someValue
If there is no match in the join, the row from the left side will still be returned.
this is an attempted fix to a crystal reports use of 2 sub reports!
I have a query that joins 3 tables, and I wanted to use a pair of sub selects that bring in the same new table.
Here is the first of the two columns in script:
SELECT ea."LOC_ID", lo."DESCR", ea."PEGSTRIP", ea."ENTITY_OWNER"
, ea."PCT_OWNERSHIP", ea."BEG_BAL", ea."ADDITIONS", ea."DISPOSITIONS"
, ea."EXPLANATION", ea."END_BAL", ea."NUM_SHARES", ea."PAR_VALUE"
, ag."DESCR", ea."EOY", ea."FAKEPEGSTRIP",
(select sum(htb.END_FNC_CUR_US_GAAP)
from EQUITY_ACCOUNTS ea , HYPERION_TRIAL_BALANCE htb
where
htb.PEGSTRIP = ea.PEGSTRIP and
htb.PRD_NBR = 0 and
htb.LOC_ID = ea.LOC_ID and
htb.PRD_YY = ea.EOY
) firstHyp
FROM ("TAXPALL"."ACCOUNT_GROUPING" ag
INNER JOIN "TAXP"."EQUITY_ACCOUNTS" ea
ON (ag."ACCT_ID"=ea."PEGSTRIP") AND (ag."EOY"=ea."EOY"))
INNER JOIN "TAXP"."LOCATION" lo ON ea."LOC_ID"=lo."LOC_ID"
WHERE ea."EOY"=2009
ORDER BY ea."LOC_ID", ea."PEGSTRIP"
When this delivers the dataset the value of "firstHyp" fails to change by pegstrip value. It returns a single total for the join and fails to put the proper by value by pegstrip.
I thought that the where clause would have picked up the joins line by line.
I don't do Oracle syntax often so what am I missing here?
TIA
Your SQL is equivilent to the following:
SELECT ea."LOC_ID", lo."DESCR", ea."PEGSTRIP",
ea."ENTITY_OWNER" , ea."PCT_OWNERSHIP",
ea."BEG_BAL", ea."ADDITIONS", ea."DISPOSITIONS" ,
ea."EXPLANATION", ea."END_BAL", ea."NUM_SHARES",
ea."PAR_VALUE" , ag."DESCR", ea."EOY", ea."FAKEPEGSTRIP",
(select sum(htb.END_FNC_CUR_US_GAAP)
from EQUITY_ACCOUNTS iea
Join HYPERION_TRIAL_BALANCE htb
On htb.PEGSTRIP = iea.PEGSTRIP
and htb.LOC_ID = iea.LOC_ID
and htb.PRD_YY = iea.EOY
where htb.PRD_NBR = 0 ) firstHyp
FROM "TAXPALL"."ACCOUNT_GROUPING" ag
JOIN "TAXP"."EQUITY_ACCOUNTS" ea
ON ag."ACCT_ID"=ea."PEGSTRIP"
AND ag."EOY"=ea."EOY"
JOIN "TAXP"."LOCATION" lo
ON ea."LOC_ID"=lo."LOC_ID"
WHERE ea."EOY"=2009
ORDER BY ea."LOC_ID", ea."PEGSTRIP"
Notice that the subquery that generates firstHyp is not in any way dependant on the tables in the outer query... It is therefore not a Correllated SubQuery... meaning that the value it generates will NOT be different for each row in the outer query's resultset, it will be the same for every row. You need to somehow put something in the subquery that makes it dependant on the value of some row in the outer query so that it will become a correllated subquery and run over and over once for each outer row....
Also, you mention a pair of subselects, but I only see one. Where is the other one ?
Use:
SELECT ea.LOC_ID,
lo.DESCR,
ea.PEGSTRIP,
ea.ENTITY_OWNER,
ea.PCT_OWNERSHIP,
ea.BEG_BAL,
ea.ADDITIONS,
ea.DISPOSITIONS,
ea.EXPLANATION,
ea.END_BAL,
ea.NUM_SHARES,
ea.PAR_VALUE,
ag.DESCR,
ea.EOY,
ea.FAKEPEGSTRIP,
NVL(SUM(htb.END_FNC_CUR_US_GAAP), 0) AS firstHyp
FROM TAXPALL.ACCOUNT_GROUPING ag
JOIN TAXP.EQUITY_ACCOUNTS ea ON ea.PEGSTRIP = ag.ACCT_ID
AND ea.EOY = ag.EOY
AND ea.EOY = 2009
JOIN TAXP.LOCATION lo ON lo.LOC_ID = ea.LOC_ID
LEFT JOIN HYPERION_TRIAL_BALANCE htb ON htb.PEGSTRIP = ea.PEGSTRIP
AND htb.LOC_ID = ea.LOC_ID
AND htb.PRD_YY = ea.EOY
AND htb.PRD_NBR = 0
GROUP BY ea.LOC_ID,
lo.DESCR,
ea.PEGSTRIP,
ea.ENTITY_OWNER,
ea.PCT_OWNERSHIP,
ea.BEG_BAL,
ea.ADDITIONS,
ea.DISPOSITIONS,
ea.EXPLANATION,
ea.END_BAL,
ea.NUM_SHARES,
ea.PAR_VALUE,
ag.DESCR,
ea.EOY,
ea.FAKEPEGSTRIP,
ORDER BY ea.LOC_ID, ea.PEGSTRIP
I agree with Charles Bretana's assessment that the original SELECT in the SELECT clause was not correlated, which is why the value never changed per row. But the sub SELECT used the EQUITY_ACCOUNTS table, which is the basis for the main query. So I removed the join, and incorporated the HYPERION_TRIAL_BALANCE table into the main query, using a LEFT JOIN. I wrapped the SUM in an NVL rather than COALESCE because I didn't catch what version of Oracle this is for.