Update in partitioned table - sql

I am trying to update a null value to 0f so it can be used for aggregation.
The following is my code:
update x:0f from data where date=2016.07.01,null x;
but it didn't work on a partitioned table, how am I able to update on a partitioned table?

The "par" error occurs when you try to update a partitioned table, which you can't do like that. Instead you have to generate the updated column and write back to disk.
If you're doing this to all date slices, your best bet might be to use the "fncol" function in the dbmaint utilities (https://github.com/KxSystems/kdb/blob/master/utils/dbmaint.md) to apply a function to the column throughout history. For example
fncol[`:/path/to/db;`data;`x;0f^]

Related

How to add column to an existing table and calculate the value

Table info:
I want to add new column and calculated the different of the alarmTime column with this code:
ALTER TABLE [DIALinkDataCenter].[dbo].[DIAL_deviceHistoryAlarm]
ADD dif AS (DATEDIFF(HOUR, LAG((alarmTime)) OVER (ORDER BY (alarmTime)), (alarmTime)));
How to add the calculation on the table? Because always there's error like this:
Windowed functions can only appear in the SELECT or ORDER BY clauses.
You are using the syntax for a generated virtual column that shows a calculated value (ADD columnname AS expression).
This, however, only works on values found in the same row. You cannot have a generated column that looks at other rows.
If you consider now to create a normal column and fill it with calculated values, this is something you shouldn't do. Don't store values redundantly. You can always get the difference in an ad-hoc query. If you store this redundantly instead, you will have to consider this in every insert, update, and delete. And if at some time you find rows where the difference doesn't match the time values, which column holds the correct value then and which the incorrect one? alarmtime or dif? You won't be able to tell.
What you can do instead is create a view for convenience:
create view v_dial_devicehistoryalarm as
select
dha.*,
datediff(hour, lag(alarmtime) over (order by alarmtime), alarmtime) as dif
from dial_devicehistoryalarm dha;
Demo: https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=b7f9b5eef33e72955c7f135952ef55b5
Remember though, that your view will probably read and sort the whole table everytime you access it. If you query only a certain time range, it will be faster hence to calculate the differences in your query instead.

Will BigQuery move records into the right partition?

I have a table that is partitioned by the timestamp contained in column X. However, during ingestion this value might be NULL, and only later on will be filled with an UPDATE.
Will BigQuery move the record to the right partition after the UPDATE?
Yes, if you execute an UPDATE statement and set the partitioning column to have different timestamps, BigQuery will move the associated rows into the appropriate partitions.

What is an efficient way to bulk copy data from a CLOB column to a VARCHAR2 column in Oracle

I have a table TEST that has 41 million+ records in it.
I have two main columns in this table that I am interested in:
MESSAGE of type CLOB
MESSAGE_C of type VARCHAR2(2048)
The table Test is range partitioned using a partition column named PART_DATE where one partition has data for one day.
I tried using the below to get the job done:
ALTER TABLE TEST ADD MESSAGE_C VARCHAR2(2048);
UPDATE TEST SET MESSAGE_C = MESSAGE;
COMMIT;
ALTER TABLE TEST DROP COLUMN MESSAGE;
ALTER TABLE TEST RENAME COLUMN MESSAGE_C TO MESSAGE;
But I got stuck on step 2 for around 4 hours. Our DBA said, these was a blocking due to full table scans.
Can someone please tell me:
What would be a better/more efficient way to get this done?
Would using the PART_DATE field in the where clause of the update query help?
Consider using an INSERT INTO SELECT to create the new table on the fly with a new name, then add the indexes after creating the table, drop the old table, and rename the new table to the old name.
It's a DML operation, so it will be significantly faster, and also isn't slowed down by server logging settings.
I've used this approach to alter tables with 500 million records a bit recently.

SQL Server Update Column based on value from another table

Please assist if I should use a trigger or procedure. I am trying to update the ScaleRating in table GSelfAssessment from GRatingScale if the Score in GSelfAssessment falls between the minimum and maximum score in GRatingScale.
GSelfAssessment table
GRatingScale Table
Preferably this should be achieved for each row on either update or insert. I believe SQL trigger is the most appropriate one. I understand the inserted/deleted concept inside a trigger after my research. E.g.
CREATE TRIGGER [dbo].[TR_GSelfAssessment_update] ON [dbo].[GSelfAssessment]
FOR UPDATE
AS
BEGIN
UPDATE GSelfAssessment
SET GSelfAssessment.ScaleRating= (Select )---this is where i have a problem-----
END
I believe there is Guru out here who can give me solution to this. I will learn a lot.
SQL Server supports computed columns. If you want ScaleRating to always be aligned with the rest of the data, then that is the best approach:
alter table GSelfAssessment
add ScaleRating as ( . . . );
This adds a new "column" that gets calculated when the value is used in a query. If the computation is expensive or you want to build an index, then use persisted so the value is actually stored with the rest of the data -- and recalculated when needed.
You can add the computed column in the create table statement as well. If you have already created the table, you can drop the column and re-add it or modify it.
You should not have that column. Join to the rating table when you need to. You can create a view if it makes it easier.
select …
from GSelfAssessment a
inner join
GRatingScale r
on (a.Score>r.MinScore and a.Score<=r.MaxScore)
Adjust/create view as required

SQL field as sum of other fields

This is not query related, what I would like to know is if it's possible to have a field in a column being displayed as a sum of other fields. A bit like Excel does.
As an example, I have two tables:
Recipes
nrecepie integer
name varchar(255)
time integer
and the other
Instructions
nintrucion integer
nrecepie integer
time integer
So, basically as a recipe has n instructions I would like that
recipes.time = sum(intructions.time)
Is this possible to be done in create table script?? if so, how?
You can use a view:
CREATE VIEW recipes_with_time AS
SELECT nrecepie, name, SUM(Instructions.time) AS total_time
FROM Recepies
JOIN Instructions USING (nrecepie)
GROUP BY Recepies.nrecepie
If you really want to have that data in the real table, you must use a trigger.
This could be done with an INSERT/UPDATE/DELETE trigger. Every time data is changed in table Instructions, the trigger would run and update the time value in Recepies.
You can use a trigger to update the time column everytime the instructions table is changed, but a more "normal" (less redundant) way would be to compute the time column via a group by clause on a join between the instructions and recepies [sic] table.
In general, you want to avoid situations like that because you're storing derived information (there are exceptions for performance reasons). Therefore, the best solution is to create a view as suggested by AndreKR. This provides an always-correct total that is as easy to SELECT from the database as if it were in an actual, stored column.
Depends pn the database vendor... In SQL Server for example, you can create a column that calculates it's value based on the values of other columns in the same row. they are called calculated columns, and you do it like this:
Create Table MyTable
(
colA Integer,
colB Integer,
colC Intgeer,
SumABC As colA + colB + colC
)
In general just put the column name you want, the word 'as' and the formula or equation to ghenerate the value. This approach uses no aditonal storage, it calculates thevalue each time someone executes a select aganist it, so the table profile remains narrower, and you get better performance. The only downsode is you cannot put an index on a calculated column. (although there is a flag in SQL server that allows you to specify to the database that it should persist the value whenever it is created or updated... In which case it can be indexed)
In your example, however, you are accessing data from multiple rows in another table. To do this, you need a trigger as suggested by other respondants.