Multiple Table Trigger Update/Delete/Insert - sql

I'm having troubles creating a SQL Server trigger to do what I want. I don't have much experience with triggers.
Basically I have a table, let's call it cluster_metadata, with metadata that describes certain attributes about an object. Then I have a second table, let's call it activities_table, with user entered data that may pertain to certain objects in the cluster_metadata table.
The cluster_metadata table is user updatable however new rows are created and deleted using a stored procedure, users can only update specific values.
The activities_table is completely user driven and users can insert/modify and delete rows.
I need a trigger that joins the data and will update the table on any modification of the cluster_metadata or activities_table.
For simplicity I've trimmed down the number of columns but the tables look something like this.
cluster_metadata:
+----------------------------------+
| Cluster | Eligible | Group |
+----------------------------------+
| Cluster1 | True | 1 |
| Cluster2 | True | 1 |
| Cluster3 | True | 2 |
| Cluster4 | False | 2 |
| Cluster5 | True | 3 |
| Cluster6 | True | 4 |
+----------------------------------+
activities_table:
+--------------------------------------------+
| Activity | ID | Group | Start Date |
+--------------------------------------------+
| Patches | 1000 | 1 | 02-01-2015 |
| Patches | 1000 | 2 | 02-10-2015 |
| Patches | 1000 | 3 | 02-20-2015 |
|SomeActivity| 1001 | 2 | 02-30-2015 |
+--------------------------------------------+
The table that I need to create and keep updated would look something like this using the data from the above two tables:
+---------------------------------------------------------------------+
| Cluster | Eligible | Group | Activity | ID | Start Date |
+---------------------------------------------------------------------+
| Cluster1 | True | 1 | Patches | 1000 | 02-01-2015 |
| Cluster2 | True | 1 | Patches | 1000 | 02-01-2015 |
| Cluster3 | True | 2 | Patches | 1000 | 02-10-2015 |
| Cluster3 | True | 2 |SomeActivity| 1001 | 02-30-2015 |
| Cluster4 | True | 2 | Patches | 1000 | 02-10-2015 |
| Cluster4 | True | 2 |SomeActivity| 1001 | 02-30-2015 |
| Cluster5 | True | 3 | Patches | 1000 | 02-20-2015 |
+---------------------------------------------------------------------+
How would I create a trigger that would do this? I would just create a view but there is some user additional input that I need to accept using this merged data.
Thanks!

Thanks for all your help. Basically what I ended up doing is created a joined view with the data from both the cluster_metadata and activities_table. From there I scripted a stored procedure which takes the appropriate data and inserts into a third table. The procedure also makes sure all the data is updated and matches the view on each execution. From there I run the procedure each time a user inputs anything to either of the tables from the web UI. Not the best solution but it's working.
Thanks everyone!

Related

Designing a database for a workout tracker

I'm designing a database for a workout tracker app. Each user should be able to track multiple workouts (routines). A workout can have multiple exercises an exercise can be used in many workouts. Each exercise will have a specific track type (weight and reps, distance and time, only reps).
My tables so far:
| User | |
|------|-------|
| id | name |
| 1 | Ilka |
| 2 | James |
| Exercise | | |
|----------|---------------------|---------------|
| id | name | track_type_id |
| 1 | Barbell Bench Press | 1 |
| 2 | Squats | 1 |
| 3 | Deadlifts | 1 |
| 4 | Rowing Machine | 3 |
| Workout | | |
|---------|---------|-----------------|
| id | user_id | name |
| 1 | 1 | Chest & Triceps |
| 2 | 1 | Legs |
| Workout_Exerice (Junction table) | |
|-----------------|------------------|------------|
| id | exersice_id | workout_id |
| 1 | 1 | 1 |
| 2 | 2 | 1 |
| 3 | 4 | 1 |
| Workout_Sets | | | |
|--------------|---------------------|------|--------|
| id | workout_exersice_id | reps | weight |
| 1 | 1 | 12 | 120 |
| 2 | 1 | 10 | 120 |
| 3 | 1 | 8 | 120 |
| 4 | 2 | 10 | 220 |
| 5 | 3 | null | null |
| TrackType | |
|-----------|-----------------|
| id | name |
| 1 | Weight and Reps |
| 2 | Reps Only |
| 3 | Distance Time |
My issue is how to incorporate the TrackType table for each workout set, my first option was to create columns in the Workout_Sets table for each tracking type (weight and reps, distance and time, only reps) but that means for many rows I will have many nulls. Another option I thought was to use an EAV type table but I'm not sure. Also do you think my design is efficient (Over-normalization)?
I would say that the most efficient way is to have nulls in your table. The alternative would require you to split many of the category's into separate tables. Also a recommendation is that you start factoring a User ID table into your database
Your description states that “Each exercise will have a specific track type” suggesting a one-to-one relationship between Exercise and TrackType, and that the relationship is unchanging. As such, the exercise table should have a TrackType column.
I suspect, however, that your problem description may be lacking specificity, making it difficult to give you sound advice. For instance, if the TrackType can vary for any given exercise, your TrackType column may belong on the Workout_Sets table. If the relationship between TrackType and Exercise/Workout_Sets is many-to-many, then you will need another junction table.
Your question regarding “over-normalization” depends upon many factors that are specific to your solution. In general, I would say no - the degree of normalization appears to be appropriate.

How to upend query to a table as new column in Access?

As a follow up to my previous question I wanted to go further with it and do other calculations based on my Diff.
Sample table:
+-------+-------+--------+-------------------+------+------+------+
| ID | RowID | User | Godzina_transakcji| Diff | Diff2| Diff3|
+-------+-------+--------+-------------------+------+------+------+
| 3 | 1 | AAA | 14:23:03 | | | |
| 8 | 2 | AAA | 14:23:57 | | | |
| 11 | 3 | AAA | 14:25:03 | | | |
| 2 | 4 | BBB | 03:37:23 | | | |
| 893 | 5 | BBB | 03:39:21 | | | |
| 5 | 6 | BBB | 05:23:11 | | | |
+-------+-------+---------+------------------+------+------+------+
Working code:
SELECT
tblTemp2.RowID,
tblTemp2.User,
tblTemp2.Godzina_transakcji,
Format(( Select TimeValue(T.Godzina_transakcji)
From tblTemp2 As T
Where tblTemp2.RowID = T.RowID + 1 And tblTemp2.User = T.User ) - TimeValue([Godzina_transakcji]), "hh:nn:ss") As Diff
FROM
tblTemp2;
So I thought the best way will be append my tblTemp with Diff, and here is where it started to hit the fan.
When I tried to change query to "Make table" my Access freezes for up to 10min. When I try to use Update query I get error about "Operation must use an updatable query.".
So my question is: what is best way to do this having in mind that next fields will be simple ifs based on calculated Diff?
For example idea about Diff2 is to check if value of hours in Diff is bigger than 4.
Edit: Hope, now it's more precise and goes along with rules :)

Teradata SQL Assistant - How can I pivot or transpose large tables with many columns and many rows?

I am using Teradata SQL Assistant Version TD 16.10.06.01 ...
I have seen a lot people transpose data for set smallish tables but I am working on thousands of clients and need the break the columns up into Line Item Values to compare orders/highlight differences between orders. Problem is it is all horizontally linked and I need to transpose it to Id,Transaction id,Version and Line Item Value 1, Line Item Value 2... then another column comparing values to see if they changed.
example:
+----+------------+-----------+------------+----------------+--------+----------+----------+------+-------------+
| Id | First Name | Last Name | DOB | transaction id | Make | Location | Postcode | Year | Price |
+----+------------+-----------+------------+----------------+--------+----------+----------+------+-------------+
| 1 | John | Smith | 15/11/2001 | 1654654 | Audi | NSW | 2222 | 2019 | $ 10,000.00 |
| 2 | Mark | White | 11/02/2002 | 1661200 | BMW | WA | 8888 | 2016 | $ 8,999.00 |
| 3 | Bob | Grey | 10/05/2002 | 1667746 | Ford | QLD | 9999 | 2013 | $ 3,000.00 |
| 4 | Phil | Faux | 6/08/2002 | 1674292 | Holden | SA | 1111 | 2000 | $ 5,800.00 |
+----+------------+-----------+------------+----------------+--------+----------+----------+------+-------------+
hoping to change the data to :
+----+----------+----------+----------+----------------+----------+----------+----------------+---------+-----+
| id | trans_id | Vers_ord | Item Val | Ln_Itm_Dscrptn | Org_Val | Updt_Val | Amndd_Ord_chck | Lbl_Rnk | ... |
+----+----------+----------+----------+----------------+----------+----------+----------------+---------+-----+
| 1 | 1654654 | 2 | 11169 | Make | Audi BLK | Audi WHT | Yes | 1 | |
| 1 | 1654654 | 2 | 11189 | Location | NSW | WA | Yes | 2 | |
| 1 | 1654654 | 2 | 23689 | Postcode | 2222 | 6000 | Yes | 3 | |
+----+----------+----------+----------+----------------+----------+----------+----------------+---------+-----+
Recently with smaller data I created a table added in Values then used a case statement when value 1 then xyz with a product join ... and the data warehouse admins didn't mention anything out of order. but I only had row 16 by 200 column table to transpose ( Sum, Avg, Count, Median(function) x 4 subsets of clients) , which were significantly smaller than my current tables to make comparisons with.
I am worried my prior method will probably slow the data Warehouse down, plus take me significant amount of time to type the SQL.
Is there a better way to transpose large tables?

Import and Export Wizard SQL Server 2012

Is there an feature on the Import/Export Wizard of SQL Server which allows me to do the following? If so, how can I go about it...
Before
+---------+-------------+----------+------+
| Name | Description | Delivery | Cost |
+---------+-------------+----------+------+
| dfdsf | dfgdfgdf | 34 | |
| sdfsdgf | dfgdfgdf | 324 | |
| dfg | dfgdfgdf | 23 | |
| dfgfdg | gdf | 43 | |
| dfgdfg | gdf | 23 | |
| fdgfdg | fgd | 443 | |
+---------+-------------+----------+------+
+---------+-------------+----------+------+
| Name | Description | Delivery | Cost |
+---------+-------------+----------+------+
| dfdsf | dfgdfgdf | 34 | |
| sdfsdgf | dfgdfgdf | 324 | |
| dfg | dfgdfgdf | 23 | |
| dfgfdg | gdf | 43 | |
| dfgdfg | gdf | 23 | |
| fdgfdg | fgd | 443 | |
| | | | 324 |
| | | | 324 |
| | | | 234 |
| | | | 234 |
| | | | 23 |
| | | | 423 |
+---------+-------------+----------+------+
So I have the table above:
I want to add the cost column in from a Flat File (CSV source, made on Excel).
Can I do this on the wizard without removing the other data - I have tried multiple different options on the wizard, but I seem to keep removing the data or the data added creates another set of row, so it will look like bottom table.
I do have a primary key on this table and I have set that to increase automatically by 1 - I have also got foreign keys, though I had to remove the relationships temporarily to allow me to even get the data onto the table.
Sorry the formatting isn't clear - The top table represents my table and the bottom table shows what happens when I input data - What I want is a the cost column aligned with the old data.
Any help would be much appreciated.
If you want to update existing records in the table you need to be able to identify a relationship between the rows in your table and the rows in your CSV file.
To update the rows in the existing table import the CSV file into a separate table. Then run an UPDATE statement like the one below to update the rows in the existing table with the data from the new table.
UPDATE T
SET T.Cost = S.Cost
FROM dbo.MyTable AS T
JOIN dbo.CsvInput AS S
ON T.ID = S.ID

Row to string value in Pervasive View

I have a table as follows
+----------------+----------+--------+
| purchase_order | text_seq | text |
+----------------+----------+--------+
| 1001 | 1 | screw |
| 1001 | 2 | m5x10 |
| 1001 | 3 | socket |
| 1002 | 1 | washer |
| 1002 | 2 | m5x10 |
+----------------+----------+--------+
From view need to get data as follows
+----------------+-------------------------+
| Purchase_order | text |
+----------------+-------------------------+
| 1001 | screw,m5x10,socket head |
| 1002 | washer,m5 |
+----------------+-------------------------+
There's not an easy way to do what you want. If you are using a recent version of PSQL, you can create a stored procedure or function to create the "text" field in the order you want (based on text_seq I would guess) and then use that result in the overall results.
My personal preference would be to retrieve the results from the database and then format them to my needs.