I have an issue with the below query:
select main.courseid
,main.coursename
,main.catid
,main.catname
,main.need_dte
from (
select t1.courseid
,t1.coursename
,t2.catid
,t2
,catname
,t2.need_dte
from t1
,t2
where t1.courseid = t2.courseid
and t1.coursename = t2.coursename
) main
left outer join (
select courseid
,coursename
,need_dte training_info
) ui on main.courseid = ui.courseid
and main.coursename = ui.coursename
and main.need_dte = ui.need_dte
I have the above scenario in which i am trying to do left outer join between the tables "main" and "training_info".
main table: a inner join between t1 and t2 to get the training and the category details.
training_info(ui): has training details without category details.
here i have few course details in "main" and "ui" tables in common. and i have few unique course records in "main" table not in "ui" table. so i am trying to extract both the unique and common records.
I am able to get the results for this join, but the issue is with the need_dte. the need_dte field is present in both tables.In the result if the records are from "main" table am able to get the need_dte field updated from the inner table t2. if the records are from "ui" table in the result, the need_dte is not being populated.
Is there any way using this join set up I need to get the need_dte for the result records from training_info table also if those records have a need_dte.
Thanks!
Is this what you want?
select t1.courseid, t1.coursename, t2.catid, t2.catname,
coalesce(ti.need_dte, t2.need_dte ) as need_dte
from t1 join
t2
on t1.courseid = t2.courseid and
t1.coursename = t2.coursename left outer join
training_info ti
on t1.courseid = ti.courseid and
t1.coursename = ti.coursename and
t2.need_dte = ti.need_dte;
I find your query with the nested subqueries, multiple levels of naming, and archaic join syntax to be difficult to read. I think the above is what you are looking for. It returns need_dte from training_info, if present, and then from t2.
Related
i have a sql query i'm running that joins & concatenates multiple tables, resulting in new columns, etc. I want to easily edit these fresh column values by double-clicking into the empty portions, like usual, but i read when joining tables they become read-only. I also wanted to attempt a regular INSERT cmd but don't understand what the table name is, since its all resulted from a lengthy query. How can i edit this queried table?
Below, i have pasted the query. For example, this spits out a new column change_products, and i want to edit those values but as mentioned above, cannot after joining/concatenating. Thanks!
SELECT change_ticket,
change_product,
change_desc,
change_state,
security_bulletin,
change_assigned_to,
affected,
remediated
FROM change_tickets t1
LEFT JOIN change_product_link t2 ON t1.id = t2.chg_id
LEFT JOIN (SELECT id, concat(product_name, ' ', product_version) AS change_product FROM products) chg_product ON t2.product_id = chg_product.id
LEFT JOIN change_sb_link t4 ON t1.id = t4.chg_id
LEFT JOIN security_bulletins t5 ON t5.id = t4.sb_id
LEFT JOIN product_sb_link t6 ON t5.id = t6.sb_id
LEFT JOIN (SELECT id, concat(product_name, ' ', product_version) AS affected FROM products) aff_soft ON t6.affected_software_id = aff_soft.id
LEFT JOIN (SELECT id, concat(product_name, ' ', product_version) AS remediated FROM products) rem_soft ON t6.remediated_software_id = rem_soft.id
WHERE change_state NOT IN ('Cancelled', 'Closed - Successful', 'Post-Verify') OR change_state IS NULL
ORDER BY 1
I have encountered very strange behavior of my query and I wasted a lot of time to understand what causes it, in vane. So I am asking for your help.
SELECT count(*) FROM main_table
LEFT JOIN front_table ON front_table.pk = main_table.fk_front_table
LEFT JOIN info_table ON info_table.pk = front_table.fk_info_table
LEFT JOIN key_table ON key_table.pk = COALESCE(info_table.fk_key_table, front_table.fk_key_table_1, front_table.fk_key_table_2)
LEFT JOIN side_table ON side_table.fk_front_table = front_table.pk
WHERE side_table.pk = (SELECT MAX(pk) FROM side_table WHERE fk_front_table = front_table.pk)
OR side_table.pk IS NULL
Seems like a simple join query, with coalesce, I've used this technique before(not too many times) and it worked right.
In this query I don't ever get nulls for side_table.pk. If I remove coalesce or just don't use key_table, then the query returns rows with many null side_table.pk, but if I add coalesce join, I can't get those nulls.
It seems key_table and side_table don't have anything in common, but the result is so weird.
Also, when I don't use side_table and WHERE clause, the count(*) result with coalesce and without differs, but I can't see any pattern in rows missing, it seems random!
Real query:
SELECT ECHANGE.EXC_AUTO_KEY, STOCK_RESERVATIONS.STR_AUTO_KEY FROM EXCHANGE
LEFT JOIN WO_BOM ON WO_BOM.WOB_AUTO_KEY = EXCHANGE.WOB_AUTO_KEY
LEFT JOIN VIEW_WO_SUB ON VIEW_WO_SUB.WOO_AUTO_KEY = WO_BOM.WOO_AUTO_KEY
LEFT JOIN STOCK stock3 ON stock3.STM_AUTO_KEY = EXCHANGE.STM_AUTO_KEY
LEFT JOIN STOCK stock2 ON stock2.STM_AUTO_KEY = EXCHANGE.ORIG_STM
LEFT JOIN CONSIGNMENT_CODES con2 ON con2.CNC_AUTO_KEY = stock2.CNC_AUTO_KEY
LEFT JOIN CONSIGNMENT_CODES con3 ON con3.CNC_AUTO_KEY = stock3.CNC_AUTO_KEY
LEFT JOIN CI_UTL ON CI_UTL.CUT_AUTO_KEY = EXCHANGE.CUT_AUTO_KEY
LEFT JOIN PART_CONDITION_CODES pcc2 ON pcc2.PCC_AUTO_KEY = stock2.PCC_AUTO_KEY
LEFT JOIN PART_CONDITION_CODES pcc3 ON pcc3.PCC_AUTO_KEY = stock3.PCC_AUTO_KEY
LEFT JOIN STOCK_RESERVATIONS ON STOCK_RESERVATIONS.STM_AUTO_KEY = stock3.STM_AUTO_KEY
LEFT JOIN WAREHOUSE wh2 ON wh2.WHS_AUTO_KEY = stock2.WHS_ORIGINAL
LEFT JOIN SM_HISTORY ON (SM_HISTORY.STM_AUTO_KEY = EXCHANGE.ORIG_STM AND SM_HISTORY.WOB_REF = EXCHANGE.WOB_AUTO_KEY)
LEFT JOIN RC_DETAIL ON stock3.RCD_AUTO_KEY = RC_DETAIL.RCD_AUTO_KEY
LEFT JOIN RC_HEADER ON RC_HEADER.RCH_AUTO_KEY = RC_DETAIL.RCH_AUTO_KEY
LEFT JOIN WAREHOUSE wh3 ON wh3.WHS_AUTO_KEY = COALESCE(RC_DETAIL.WHS_AUTO_KEY, stock3.WHS_ORIGINAL, stock3.WHS_AUTO_KEY)
WHERE STOCK_RESERVATIONS.STR_AUTO_KEY = (SELECT MAX(STR_AUTO_KEY) FROM STOCK_RESERVATIONS WHERE STM_AUTO_KEY = stock3.STM_AUTO_KEY)
OR STOCK_RESERVATIONS.STR_AUTO_KEY IS NULL
Removing LEFT JOIN WAREHOUSE wh3 gives me about unique EXC_AUTO_KEY values with a lot of NULL STR_AUTO_KEY, while leaving this row removes all NULL STR_AUTO_KEY.
I recreated simple tables with numbers with the same structure and query works without any problems o.0
I have a feeling COALESCE is acting as a REQUIRED flag for the joined table, hence shooting the LEFT JOIN to become an INNER JOIN.
Try this:
SELECT COUNT(*)
FROM main_table
LEFT JOIN front_table ON front_table.pk = main_table.fk_front_table
LEFT JOIN info_table ON info_table.pk = front_table.fk_info_table
LEFT JOIN key_table ON key_table.pk = NVL(info_table.fk_key_table, NVL(front_table.fk_key_table_1, front_table.fk_key_table_2))
LEFT JOIN (SELECT fk_, MAX(pk) as pk FROM side_table GROUP BY fk_) st ON st.fk_ = front_table.pk
NVL might behave just the same though...
I undertood what was the problem (not entirely though): there is a LEFT JOIN VIEW_WO_SUB in original query, 3rd line. It causes this query to act in a weird way.
When I replaced the view with the other table which contained the information I needed, the query started returning right results.
Basically, with this view join, NVL, COALESCE or CASE join with combination of certain arguments did not work along with OR clause in WHERE subquery, all rest was fine. ALthough, I could get the query to work with this view join, by changing the order of joined tables, I had to place table participating in where subquery to the bottom.
Why does the below query fail when I add the second LEFT JOIN statement? The error states "Multi-part identifier T3.ConfigIDx could not be bound". Prior to adding the statement the column T3.ConfigIDx showed in the results. I tried with and with out T3.
I removed some code within the INNER JOINS for brevity.
-- Add CfgDescription to ComponentID include QuantityWH for all components 'Used' or blank found in the order.
-- Attach Line information like Quantity and DiscountRate from the Order using Configuration ID.
SELECT
BDCComponentAttributes.componentID AS ComponentID,
BDCComponentAttributes.Value AS CfgDescription,
CAST (BDC10.Value AS INT) AS QuantityWH,
CfgIDx,
T3.ConfigIDx
FROM BDCComponentAttributes
Left join BDCComponentAttributes BDC10 on BDC10.ComponentID = BDCComponentAttributes.componentID and BDC10.ComponentAttributeName = 'QuantityWH'
Left join OrderDetails on OrderDetails.ConfigurationID = T3.ConfigIDx
INNER JOIN
(
-- Select ComponentID's and their respective CfgDescription for components found in order. This creates derived table T3.
INNER JOIN
(
-- Select Components in the order NOT 'NotUsed'. This creates derived table T2.
INNER JOIN
(
-- Select ConfigurationID's for components of the order. This creates derived table T1.
) AS T1
ON BDCComponents.CfgID = T1.CfgIDx
) AS T2
ON BDCComponentAttributes.ComponentID = T2.ComponentID
WHERE BDCComponentAttributes.ComponentAttributeName = 'PartInSystem' AND ( 'Used' = IsNull(BDCComponentAttributes.Value,'Used') OR BDCComponentAttributes.Value='Used')
) AS T3
ON BDCComponentAttributes.componentID = T3.ComponentID
WHERE BDCComponentAttributes.ComponentAttributeName = 'CfgDescription'
ORDER BY ComponentID
The from clause in your query starts:
FROM BDCComponentAttributes Left join
BDCComponentAttributes BDC10
on BDC10.ComponentID = BDCComponentAttributes.componentID and
BDC10.ComponentAttributeName = 'QuantityWH' Left join
OrderDetails
on OrderDetails.ConfigurationID = T3.ConfigIDx
When a query is compiled, the from clause is interpreted in lexical ordering -- that is, in the same "left-to-right" "top-to-bottom" way that we read. When the symbol T3 is encountered, it is not defined. That is causing your error. SQL does not have "look-ahead" to see that it is defined later in the from clause.
You can fix this by moving the join condition after the definition of T3.
I keep receiving a syntax error on this particular statement.
SELECT tbl1.ProjectID, tbl1.EntryDate AS StartDate, tbl2.EntryDate AS EndDate,
(tbl3.ChecklistDayMax - tbl3.ChecklistDayMin + 1) AS DaysAllotted,
(SELECT ProjectPriority FROM project_master WHERE ProjectID = tbl1.ProjectID) AS Priority,
tbl3.MilestoneName,
IIF(Priority = 1, tbl3.BonusDaysFH,
IIF(Priority = 2, tbl3.BonusDaysFM,
IIF(Priority = 3, tbl3.BonusDaysFL))) AS BonusDaysAllotted
FROM (((checklist_entries AS tbl1
INNER JOIN checklist_entries AS tbl2 ON tbl1.ProjectID = tbl2.ProjectID)
INNER JOIN milestone_def AS tbl3 ON [#milestoneID] = milestone_def.MilestoneDefID)
INNER JOIN project_active_status AS tbl4 ON tbl1.ProjectID = project_active_status.ProjectID)
WHERE tbl1.ChecklistDay = tbl3.ChecklistDayMin
AND tbl2.ChecklistDay = tbl3.ChecklistDayMax
AND tbl4.ProjectIsOpen = FALSE;
The error says Syntax Error In Join Operation and then it highlights milestone_def right after the 2nd INNER JOIN. Funny thing is, if I switch this line...
INNER JOIN milestone_def AS tbl3 ON [#milestoneID] = milestone_def.MilestoneDefID)
with this line...
INNER JOIN milestone_def AS tbl3 ON [#milestoneID] = tbl3.MilestoneDefID)
I get the error Join Expression Not Supported and then it highlights...
[#milestoneID] = tbl3.MilestoneDefID)
But as you can see, in the first join...
INNER JOIN checklist_entries AS tbl2 ON tbl1.ProjectID = tbl2.ProjectID
I name it tbl2 and then use tbl2.ProjectID and the expression works just fine. Ultimately, I need to get this to work, regardless how how I name these things.
[#milestoneID] is a parameter passed into the query to match milestone_def.MilestoneDefID
[Expanded from comments.] This is just a hunch, as I don't have access to Access (ha ha), but your query currently specifies an INNER JOIN that doesn't actually relate the table to the rest of the query:
...
INNER JOIN milestone_def AS tbl3
ON [#milestoneID] = milestone_def.MilestoneDefID
...
The ON clause references only an external variable, so isn't relevant to the JOIN operation, making this effectively a CROSS JOIN with a separate WHERE condition:
...
CROSS JOIN milestone_def AS tbl3
...
WHERE [#milestoneID] = milestone_def.MilestoneDefID
...
Looking at the bottom of your query, you have the actual join conditions for this table in the WHERE clause; these should be swapped into the ON clause, so that it actually specifies the INNER JOIN condition:
...
INNER JOIN milestone_def AS tbl3
ON tbl1.ChecklistDay = tbl3.ChecklistDayMin
AND tbl2.ChecklistDay = tbl3.ChecklistDayMax
...
WHERE [#milestoneID] = milestone_def.MilestoneDefID
...
It's certainly more logical that way, and it will possibly solve the problem Access's parser is having understanding your query.
Since the problem is with the joins, you would be wise to investigate the issue with a simpler query.
SELECT *
FROM
((checklist_entries AS tbl1
INNER JOIN checklist_entries AS tbl2
ON tbl1.ProjectID = tbl2.ProjectID)
INNER JOIN milestone_def AS tbl3
ON [#milestoneID] = milestone_def.MilestoneDefID)
INNER JOIN project_active_status AS tbl4
ON tbl1.ProjectID = project_active_status.ProjectID
Notice you have aliased the table names. Therefore you must use those aliases instead of the table names in the ON clauses.
SELECT *
FROM
((checklist_entries AS tbl1
INNER JOIN checklist_entries AS tbl2
ON tbl1.ProjectID = tbl2.ProjectID)
INNER JOIN milestone_def AS tbl3
ON tbl1.[#milestoneID] = tbl3.MilestoneDefID)
INNER JOIN project_active_status AS tbl4
ON tbl1.ProjectID = tbl4.ProjectID
I don't know what [#milestoneID] is or where it comes from. My best guess is it's a field in checklist_entries, so I qualified it with the tbl1 alias.
I think HansUp's answer is pointing you in the right direction. One other thing that I noticed is that you have a series of three nested IIFs and the final one only has a test and a true but is missing the false parameter. I thought that all three were compulsory.
I have this problem regarding sql which i will be using in a webservice if I can get this right. What I wanted to do is create a summary report of a transaction. The transaction have header and lines. In a transaction, we are going to input a many planks.
After the inputing, I would like to produce a report that would add all the plank that belongs to a category, then multiply all the planks by the price of that supplier so that I can have the total amount. Here is a pic:
below is my sql which produce wrong output:
select
t1.transaction_num,
wo1.wood_classification_desc,
wo2.wood_specie_desc,
sum(t2.board_foot) as total_board_foot,
su1.price,
sum(t2.board_foot*su1.price) as total_amount
from
"transaction_hdr" t1
left join "transaction_lne" t2 on (t1.transaction_id = t2.transaction_id)
left join "supplier" su2 on (t1.supplier_id = su2.supplier_id)
left join "supplier_price" su1 on (t2.price = su1.price)
left join "wood_classification" wo1 on (t2.wood_classification_id = wo1.wood_classification_id)
left join "wood_specie" wo2 on (wo1.wood_specie_id = wo2.wood_specie_id)
group by
t1.transaction_num,wo1.wood_classification_desc,su1.price,su2.supplier_name,wo2.wood_specie_desc
order by transaction_num,wo2.wood_specie_desc
Evrytime I run that sql, it produces somthing like this:
the transaction that i test only have five planks. 4 planks under Mahogany 6" wider - 7ft. up and 1 Mahogany 5" wider - 7ft. up.
I would guess, that in one of the left joins you have more than one record, which means it give you wrong sum (group by will affect the set after the left join).
Just run the sql without the grouping and check what you get.
So it's probably not the multiplication that causes the problem, it's the sum.
Do you have more than one record in supplier_price with price = 13.33 ? That would be my guess, as all the other joins appear to be on primary keys..
EDIT:
Your problem is that you're joining to supplier_price on the price field, which is not a valid key. Given that your output doesn't take anything from the supplier_price table, I'd be inclined to remove it from the query altogether as below:
select
t1.transaction_num,
wo1.wood_classification_desc,
wo2.wood_specie_desc,
sum(t2.board_foot) as total_board_foot,
t2.price,
sum(t2.board_foot*t2.price) as total_amount
from
"transaction_hdr" t1
left join "transaction_lne" t2 on (t1.transaction_id = t2.transaction_id)
left join "supplier" su2 on (t1.supplier_id = su2.supplier_id)
left join "wood_classification" wo1 on (t2.wood_classification_id = wo1.wood_classification_id)
left join "wood_specie" wo2 on (wo1.wood_specie_id = wo2.wood_specie_id)
group by
t1.transaction_num,wo1.wood_classification_desc,t2.price,su2.supplier_name,wo2.wood_specie_desc
order by transaction_num,wo2.wood_specie_desc
This may solve the issue. But it would help if you provided the relationships between the tables (and the tables' primary keys):
select
t1.transaction_num,
wo1.wood_classification_desc,
wo2.wood_specie_desc,
sum(t2.board_foot)
as total_board_foot,
( SELECT DISTINCT su1.price
FROM "supplier_price" su1
WHERE t2.price = su1.price
) AS price,
sum(t2.board_foot) *
( SELECT DISTINCT su1.price
FROM "supplier_price" su1
WHERE t2.price = su1.price
)
as total_amount
from
"transaction_hdr" t1
left join "transaction_lne" t2
on (t1.transaction_id = t2.transaction_id)
left join "supplier" su2
on (t1.supplier_id = su2.supplier_id)
left join "wood_classification" wo1
on (t2.wood_classification_id = wo1.wood_classification_id)
left join "wood_specie" wo2
on (wo1.wood_specie_id = wo2.wood_specie_id)
group by
t1.transaction_num
, wo1.wood_classification_desc
, su2.supplier_name
, wo2.wood_specie_desc
order by transaction_num
, wo2.wood_specie_desc