SQL Server Update Column based on value from another table - sql

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

Related

Adding a column to existing table in access without using any relationship

I am working on a project in ACCESS 2010 that requires me to give a rank to 30000 products based on their sales. I have tried using a query to do the ranking and it takes a long time. (Please find codes at Making the ranking query efficient)
I figured out that instead, I can just sort the table based on the Sales column and add a field with numbers 1 to 30000.
So is there a way to add such a column, i.e. a column without any relationship to the existing table.
Add a field to the actual table? If that's the case, make a table and run this query:
ALTER TABLE yourTableName
ADD COLUMN yourColumnName AUTOINCREMENT(1, 1)

SQL computed column for sum of data in another table

I have two tables:
DiskUsage Table StatisticsTable
Server DiskUsage(GB) Total Disk Usage xxxx
1 10
2 212
3 11
I need to create the "Total Disk Usage" as a column which works out the Sum of the "DiskUsage" column. This would need to be dynamic as more servers will be added overtime to the "DiskUsage" table.
I've done some looking into this - and I believe a Computed Column would be the easiest way to achieve this, but I'm not sure how to a). reference the other tables data or b). dynamically obtain the total of that column.
What is the issue with just running a query?
select sum(diskusage)
from diskusage;
This seems simple enough and unless you have millions of rows, performance should be quite fast.
Create a trigger
CREATE TRIGGER test
ON DiskUsage
after INSERT, UPDATE
AS
BEGIN
UPDATE StatisticsTable
SET TotalDiskUsage = (SELECT Sum(DiskUsage)
FROM DiskUsage)
END
Or as Mentioned by King.code create a view instead of having a table
CREATE VIEW StatisticsTable
AS
SELECT Sum(DiskUsage)
FROM DiskUsage

How to define records count to a table that updated only when the table is updated

I want to defint a view (or something else)
that will save a static variable of the table count.
I want this variable to be update only when the table is updated,
this way each time I call the view it will not calculate the count, just return the value.
in the past someone told me that "select count_bit(Id) from table1" will do the job.
is it right?
I want to use the variable in mvc site using entity-framework . How do I do it?
Create a separate table to store the count value.
Create insert, update and delete triggers for table1, which calculates the new count and updates the count value.
But do you really need to do this? Are you having performance problems with select count(*) from table1? You know, triggers will slow down all update, delete and inserts a bit.
Just use a Select Count to the table ,even if you select just a column and count that for your rows or select the the whole table to count the complete table data...put your count expression after your update is done .

SQL - Selecting a field from another table using a primary key in a trigger

I have two tables in my database, one is Transactions and the other is TransactionHistories. The latter is essentially an auditing table, whereby a trigger executes on insert, update and delete on Transactions to capture a screenshot of the data.
I am successfully retrieving all of the data stored in the Transactions table where the columns match, but the difficulty comes where I am trying to retrieve data from another table using a foreign key. For instance:
The transaction table has a field "TransactionType_TransactionTypeId", but in the audit table we wish to store its 'name' equivalent as "TransactionTypeName". This needs to be populated from the "TransactionTypes" table, which has the fields "TransactionTypeId" and "Name".
I am struggling to write a query to retrieve this as we wish. I am trying something similar to the following but having little success:
SELECT #TransactionTypeName=Name
FROM TransactionTypes
WHERE inserted.TransactionType_TransactionTypeId=TransactionTypes.TransactionTypeId;
I'm assuming that is a syntactic nightmare. If someone could point me in the right direction I would be extremely grateful!
well to get a name you should do the following
select #TransactionTypeName = TT.Name
from inserted as i
left outer join TransactionTypes as TT on TT.TransactionTypeId = i.TransactionType_TransactionTypeId
but you have to know that inserted table can have more than one row, and you are getting value for only one row.

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.