UPDATE query joining table and subselect in ACCESS - sql

I am trying to update a field of my table1 using the following code but I receive the following error message:3073 operation must use an updateable query.
UPDATE table1 a
INNER JOIN (SELECT COUNT(somevalue) AS Total,ID
FROM ReadsPNPA GROUP BY ID) b
ON a.ID=b.ID
SET a.Total = b.Total
Any ideas? the subselect query works on its own.

Use a DCount expression instead of a subquery to do your UPDATE ...
UPDATE table1 a
SET a.Total = DCount('somevalue', 'ReadsPNPA', '[ID]=' & a.ID);
Access UPDATE queries are fussy. Techniques like subqueries or GROUP BY cause Access to treat the query as "not updateable". See Why is my query read-only? for more information.
You can use domain aggregate functions (such as DCount, DSum, DAvg, etc.) so that Access will treat the query as updateable.

Related

BigQuery select, join from multiple datasets and avoid name conflicts

Imagine I have several datasets and tables.
Format: dataset.table.field
dataset01.table_xxx.field_z
dataset02.table_xxx.field_z
I try to write smth like
select
dataset01.table_xxx.field_z as dataset01_table_xxx_field_z,
dataset02.table_xxx.field_z as dataset02_table_xxx_field_z
from dataset01.table_xxx
join dataset02.table_xxx on dataset02.table_xxx.field_z = dataset01.table_xxx.field_z
to avoid conflicting names
BigQuery says that dataset01.table_xxx.field_xxx is unrecognised name in SELECT clause.
it complains about unrecognised name in join clause too.
Query works if I remove dataset01, dataset02 from SELECT clause and on condition
What is the right way to refer fields in such case?
select
t1.field_z as dataset01_table_xxx_field_z,
t2.field_z as dataset02_table_xxx_field_z
from dataset01.table_xxx t1
join dataset02.table_xxx t2
on t2.field_z = t1.field_z

SQL: Is the newly selected temp table in FROM clause not passed to the sub-query in WHERE clause?

here's a question I'm in trouble with. Basically, there are originally two tables: "a" and "b". I firstly "joined" (without using JOIN clause) them together with some conditions: "a.id=b.id", "b.class="xxx"". Then I name that temp table as A, and want to select the data with the highest income within the people in A.
The error returns "the relation A doesn't exist." And the error arrow turns to the clause "select max(A.income) from A". Therefore, I suspect that the temp table A created in FROM clause will not be passed to the sub-query in WHERE clause?
select * from
(select * from a,b where a.id=b.id and b.class='xxx') as A
where A.income = all
(select max(A.income) from A)
I've encountered this problem while using Postgres, but I think it may also happen in other languages like MYSQL or MSSQL. Are there any possible solutions to solve that? Without using WITH clause? Thanks. (The reason why I say "sub-query" instead of "query" is because I've tried terms like "where A.income>1000" and they all work)
The problem is that your alias a hides the table with the same name. Use a different alias name.
It is unclear whether you want to select from the original table a in the subquery or from the alias. If it is the former, then the above will solve your problem.
If you want to reference the alias in the subquery, you had better use a common table expression:
WITH alias_name AS (/* your FROM subquery */)
SELECT ... /* alias_name can be used in a subquery here */
You can try the below -
select * from a join b on a.id=b.id where b.class='xxx'
and income = all (select max(income) from a join b on a.id=b.id where b.class='xxx')

Access SQL: Update list with Max() and Min() values not possible

I've a list of dates: list_of_dates.
I want to find the max and min values of each number with this code (#1).
It works how it should, and therefore I get the table MinMax
Now I want to update a other list (list_of_things) with these newly acquired values (#2).
However, it is not possible.
I assume it's due to DISTINCT and the fact that I always get two rows per number, each with the min and max values. Therefore an update is not possible.
Unfortunately I don't know any other way.
#1
SELECT a.number, b.MaxDateTime, c.MinDateTime
FROM (list_of_dates AS a
INNER JOIN (
SELECT a.number, MAX(a.dat) AS MaxDateTime
FROM list_of_dates AS a
GROUP BY a.number) AS b
ON a.number = b.number)
INNER JOIN (SELECT a.number, MIN(a.dat) AS MinDateTime
FROM list_of_dates AS a
GROUP BY a.number) AS c
ON a.number = c.number;
#2
UPDATE list_of_things AS a
LEFT JOIN MinMax AS b
ON a.number = b.number
SET a.latest = b. MaxDateTime, a.ealiest = b.MinDateTime```
No part of an MS Access update query can contain aggregation, else the resulting recordset becomes 'not updateable'.
In your case, the use of the min & max aggregate functions within the MinMax subquery cause the final update query to become not updateable.
Whilst it is not always advisable to store aggregated data (in favour of generating an output from transactional data using queries), if you really need to do this, here are two possible methods:
1. Using a Temporary Table to store the Aggregated Result
Run a select into query such as the following:
select
t.number,
max(t.dat) as maxdatetime,
min(t.dat) as mindatetime
into
temptable
from
list_of_dates t
group by
t.number
To generate a temporary table called temptable, then run the following update query which sources date from this temporary table:
update
list_of_things t1 inner join temptable t2
on t1.number = t2.number
set
t1.latest = t2.maxdatetime,
t1.earliest = t2.mindatetime
2. Use Domain Aggregate Functions
Since domain aggregate functions (dcount, dsum, dmin, dmax etc.) are evaluated separately from the evaluation of the query, they do not break the updateable nature of a query.
As such, you might consider using a query such as:
update
list_of_things t1
set
t1.latest = dmax("dat","list_of_dates","number = " & t1.number),
t1.earliest = dmin("dat","list_of_dates","number = " & t1.number)
It's a shot in the dark, but try adding DistinctRow as per SQL Update woes in MS Access - Operation must use an updateable query
Also try using an inner join. If you need to, you can run an update to a null value first for all the records in the query to simulate the effect of the outer join.

Cannot update a table using a simple inner join

I have 2 tables in access 2007.
See attached picture to see the structure of the tables and the expected result.
I am trying to update the quantity field (ITQTY) in TABLE_BLNC by summarizing all the quantity field (LOCQTY) from TABLE_DTL for same items (LOITNBR=ITNBR).
In TABLE_BLNC, the item is unique while in TABLE_DTL, the item can be in multiple records.
My query is:
UPDATE TABLE_BLNC INNER JOIN
(
SELECT LOITNBR, Sum(LOCQTY) AS SumOfLOCQTY FROM TABLE_DTL GROUP BY LOITNBR) AS DTL
ON TABLE_BLNC.ITNBR=DTL.LOITNBR SET TABLE_BLNC.ITQTY = DTL.SumOfLOCQTY;
I am getting the error:
Operation must use an updateable query.
Domain Aggregate functions can be useful when Access complains that an UPDATE is not updateable. In this case, use DSum() ...
UPDATE TABLE_BLNC
SET ITQTY =
DSum("LOCQTY", "TABLE_DTL", "LOITNBR='" & ITNBR & "'");
Index TABLE_DTL.LOITNBR for optimum performance.
One of the great annoyances of Access SQL is its inability to update a table from an non-updatable source. Non-updatable sources include read-only links to ODBC tables, and GROUP BY (summary) queries.
What I always do is:
Copy the structure of TABLE_BLNK to a temp table: TABLE_BLNK_temp.
In your code, first delete the temp:
DELETE * FROM TABLE_BLNK_temp;
Insert the result of your summary query into temp:
INSERT INTO TABLE_BLNK_temp (ITNBR, ITQTY)
SELECT LOITNBR, Sum(LOCQTY) AS SumOfLOCQTY
FROM TABLE_DTL GROUP BY LOITNBR;
Update TABLE_BLNK from TABLE_BLNK_temp:
UPDATE TABLE_BLNC INNER JOIN TABLE_BLNK_temp AS t
ON TABLE_BLNC.ITNBR = t.ITNBR
SET TABLE_BLNC.ITQTY = t.ITQTY;
While it is an extra step or two, this approach:
Always works
Is more performant than Domain Aggregate functions for larger datasets

ADO SQL update table with result of group by query

I am trying to update records in an .mdb table with the number of records containing the same value.
The SQL below does not work but I think gives an indication of what I am trying to achieve.
UPDATE table1 AS A
INNER JOIN (SELECT PH_BSP , Count(PH_BSP) AS PHCOUNT FROM table1 GROUP BY PH_BSP) AS B
ON A.PH_BSP=B.PH_BSP
SET A.PH_SORT = B.PHCOUNT;
Any ideas?
If you are doing this in Access, you need to use a domain aggregate function:
UPDATE table1
SET PH_SORT = DCount("PH_BSP","Table1","PH_BSP='" & PH_BSP & "'")
The above assumes that PH_BSP is a text field, drop the single quotes if it is numeric.
Untested, but setting out the statement thusly this should solve your issue
UPDATE A
SET A.PH_SORT = B.PHCOUNT
From table1 AS A
INNER JOIN (SELECT PH_BSP , Count(PH_BSP) AS PHCOUNT FROM table1 GROUP BY PH_BSP) AS B
ON A.PH_BSP=B.PH_BSP
Edit:
Your problem might be from your sub query, I would try putting that part into a separate Access Query and see how it goes. From memory I used to have a lot of trouble with Access and subqueries, square brackets would also sometimes help, but unreliable from memory.
Have you tried something alike?
update table1 as a
set a.ph_sort = (
select COUNT(b.ph_bsp) as phcount
from table1 b
where b.ph_bsp = a.ph_bsp)
I'm assuming SQL Server here.
But this or something alike should do it, I guess.