PostgreSQL update table with average vale from another table - postgresql

I have tried this three different ways and PostgreSQL still doesn't like that I am "aggregate functions are not allowed in UPDATE". I am not sure how to this without doing that. Can someone point me in the right direction to populate my average Wage field with my average wages?
Attempt 1:
UPDATE public."JobCategory"
SET "AverageWage" = round(avg("Wage"), 4)
FROM public."Employees" WERE "Wage" > 0
Attempt 2:
UPDATE public."JobCategory" c
INNER JOIN (
SELECT round(avg("Wage"), 4) as average
FROM public."Employees"
) x ON c."Index" = x."JobIndex"
SET c."AverageWage" = x.average
Attempt 3:
UPDATE public."JobCategory" AS v
SET "AverageWage" = s.round(avg("Wage"), 4)
FROM public."Employees" AS s
WHERE v."Index" = s."JobIndex"

You can do this with a subquery:
WITH subq AS (
SELECT round(avg(Wage), 4) as average
FROM public.Employees
)
UPDATE public.JobCategory jc
SET AverageWage = subq.average
FROM subq

Related

db2 sql update to calculate totals column single update

trying to calculate a moving total for a yearly column bucket, the monthly buckets are rolling as well so I'm not sure if possible in single update, I want the prev12 column to equal the updated monthly 1-12 after the move
update table_a as a1
set (a1.col1, a1.col2, a1.col3,a1.col4,a1.col5,a1.col6,
a1.col7, a1.col8,a1.col9, a1.col10,a1.col11,a1.col12,
a1.col_prev12) =
(select
a2.col, a2.col1, a2.col2, a2.col3,
a2.col4, a2.col5, a2.col6,
a2.col7, a2.col8, a2.col9,
a2.col10, a2.col11,
a2.col1 + a2.col2 + a2.col3 + a2.col4 +
a2.col5 + a2.col6 + a2.col7 + a2.col8 +
a2.col9 + a2.col10 + a2.col11 + a2.col12
from table_a as a2
where a1.store = a2.store and a1.line = a2.line and a1.item = a2.item
)
where a1.last_roll_date = current date
Not quite sure what you want, but yes you can update multiple columns in on UPDATE
Also, you might find this form of UPDATE easier
UPDATE (
SELECT *
, LAG(COL1) OVER(PARTITION BY store, line ORDER BY last_roll_date) as PREV_COL1
, LAG(COL1) OVER(PARTITION BY store, line ORDER BY last_roll_date) as PREV_COL2
FROM
table_a
)
SET COL1 = PREV_COL1
, COL2 = PREV_COL2
WHERE
last_roll_date = current date
or if not, you probably just a where a1.last_roll_date = a2.last_role_date - 1 month in your original sub-select

UPDATE with Aggregate SELECT - SET columns 0 when SELECT is empty

I have the following UPDATE statement
UPDATE stuff
SET stuff.total = t.total
FROM (
SELECT SUM(price) FROM things WHERE stuff_id = ? GROUP BY stuff_id
) t
WHERE stuff.id = ?
This works fine when there are actually rows in things, but when not no UPDATE is executed (which I guess makes sense). What would be an elegant way to set stuff.total to 0 in that case? I'd like to do it in one query.
I already tried SET stuff.total = coalesce(t.total, 0) but it had no effect.
You haven't used coalesce in the right place. Also, GROUP BY can be omitted. Try this query:
UPDATE stuff
SET stuff.total = t.total
FROM (
SELECT coalesce(SUM(price), 0) FROM things WHERE stuff_id = ?) t
WHERE stuff.id = ?

How to create an Update statement from a subquery in TSQL

I need to update all records that match my criteria. But the Sql below is giving this error:
Subquery returned more than 1 value. This is not permitted when the
subquery follows =, !=, <, <= , >, >= or when the subquery is used as
an expression.
-- Set MasterAccountId = NULL where there is no Receivable with equivalent BillingAccountId and TaskAccountId
UPDATE R
SET R.MasterAccountId = NULL
FROM Receivable R
WHERE EXISTS ( SELECT * FROM MasterAccount M
WHERE (ISNULL(M.BillingAccountId, 0) > 0 AND M.BillingAccountId = R.BillingAccountId) OR
(ISNULL(M.TaskAccountId, 0) > 0 AND M.TaskAccountId = R.TaskAccountId))
Basically, I need to update all records that return in that subquery.
Does any one know how to fix it?
Can you give a try on this. This is base from the repond of https://stackoverflow.com/users/40655/robin-day on this link How do I UPDATE from a SELECT in SQL Server?.
UPDATE
R
SET
R.MasterAccountId = NULL
FROM
Receivable R
INNER JOIN
MasterAccount M
ON
(ISNULL(M.BillingAccountId, 0) > 0 AND M.BillingAccountId = R.BillingAccountId) OR
(ISNULL(M.TaskAccountId, 0) > 0 AND M.TaskAccountId = R.TaskAccountId))
I don't think you are getting the said error in posted query May be somewhere else. Again in your EXISTS subquery, instead of saying select * ... it's always better to say WHERE EXISTS ( SELECT 1 FROM MasterAccount M
Also try using the JOIN version of this query instead like
UPDATE R
SET R.MasterAccountId = NULL
FROM Receivable R
JOIN MasterAccount M ON M.BillingAccountId = R.BillingAccountId
OR M.TaskAccountId = R.TaskAccountId
WHERE ISNULL(M.BillingAccountId, 0) > 0
OR ISNULL(M.TaskAccountId, 0) > 0;

Returning distinct columns from left outer join in db2

SELECT
nzy.NZPYYD
,nzy.NZZSYG
,nzy.NZJRYG
,acn.ANITCD
FROM
ACNTRA acn
LEFT OUTER JOIN NZYTFL nzy
ON (
nzy.NZCNO1 = acn.ANCNO1
AND nzy.NZCNO2 = acn.ANCNO2
AND nzy.NZCNO3 = acn.ANCNO3
AND nzy.NZCNO4 = acn.ANCNO4
AND nzy.NZCNO5 = acn.ANCNO5
AND nzy.NZSLKI = acn.ANSLKI
AND nzy.NZDLTM = ''
)
WHERE
acn.ANDLTM = ''
AND acn.ANTKCD = '1029'
AND nzy.NZTXKB = 1
The problem here is it gives 2 rows result.I want to get one unique row from the result of left outer join .Any help?
If both rows are identical, try
SELECT DISTINCT
nzy.NZPYYD
,nzy.NZZSYG
,nzy.NZJRYG
,acn.ANITCD
If not, you can try to SUM(), CONCAT(), MAX() or whatever the column with different values.
Difficult to be more precise without a sample output.

How to determine the size of a Full-Text Index on SQL Server 2008 R2?

I have a SQL 2008 R2 database with some tables on it having some of those tables a Full-Text Index defined. I'd like to know how to determine the size of the index of a specific table, in order to control and predict it's growth.
Is there a way of doing this?
The catalog view sys.fulltext_index_fragments keeps track of the size of each fragment, regardless of catalog, so you can take the SUM this way. This assumes the limitation of one full-text index per table is going to remain the case. The following query will get you the size of each full-text index in the database, again regardless of catalog, but you could use the WHERE clause if you only care about a specific table.
SELECT
[table] = OBJECT_SCHEMA_NAME(table_id) + '.' + OBJECT_NAME(table_id),
size_in_KB = CONVERT(DECIMAL(12,2), SUM(data_size/1024.0))
FROM sys.fulltext_index_fragments
-- WHERE table_id = OBJECT_ID('dbo.specific_table_name')
GROUP BY table_id;
Also note that if the count of fragments is high you might consider a reorganize.
If you are after a specific Catalogue
Use SSMS
- Clik on [Database] and expand the objects
- Click on [Storage]
- Right Click on {Specific Catalogue}
- Choose Propertie and click.
IN General TAB.. You will find the Catalogue Size = 'nn'
I use something similar to this (which will also calculate the size of XML-indexes, ... if present)
SELECT S.name,
SO.name,
SIT.internal_type_desc,
rows = CASE WHEN GROUPING(SIT.internal_type_desc) = 0 THEN SUM(SP.rows)
END,
TotalSpaceGB = SUM(SAU.total_pages) * 8 / 1048576.0,
UsedSpaceGB = SUM(SAU.used_pages) * 8 / 1048576.0,
UnusedSpaceGB = SUM(SAU.total_pages - SAU.used_pages) * 8 / 1048576.0,
TotalSpaceKB = SUM(SAU.total_pages) * 8,
UsedSpaceKB = SUM(SAU.used_pages) * 8,
UnusedSpaceKB = SUM(SAU.total_pages - SAU.used_pages) * 8
FROM sys.objects SO
INNER JOIN sys.schemas S ON S.schema_id = SO.schema_id
INNER JOIN sys.internal_tables SIT ON SIT.parent_object_id = SO.object_id
INNER JOIN sys.partitions SP ON SP.object_id = SIT.object_id
INNER JOIN sys.allocation_units SAU ON (SAU.type IN (1, 3)
AND SAU.container_id = SP.hobt_id)
OR (SAU.type = 2
AND SAU.container_id = SP.partition_id)
WHERE S.name = 'schema'
--AND SO.name IN ('TableName')
GROUP BY GROUPING SETS(
(S.name,
SO.name,
SIT.internal_type_desc),
(S.name, SO.name), (S.name), ())
ORDER BY S.name,
SO.name,
SIT.internal_type_desc;
This will generally give numbers higher than sys.fulltext_index_fragments, but when combined with the sys.partitions of the table, it will add up to the numbers returned from EXEC sys.sp_spaceused #objname = N'schema.TableName';.
Tested with SQL Server 2016, but documentation says it should be present since 2008.