I have a mysql database table called "character" with columns like name, strength, intelligence, skill. I want to create a column that sums up strength, intelligence and skill AUTOMATICALLY. Is this possible?
I have seen loads of pages showing how to do queries. I did a query just fine, such as
select (str+intel+skl) as sum from character;
It returns a sum just fine.
But what I'm missing (don't understand) is how to:
either AUTOMATE that query into my mysql db (for example, when I do "select * from character", it will show "strength, intelligence, skill, sum"),
OR where/how to incorporate the mysql query into my rails app so that SUM shows up in real time, and when edits to, for e.g. strength occur, the SUM is updated accordingly.
A key point, I am summing columns across a row (strength, intelligence, skill), not summing a column (strengths of several characters).
Your best option is to use a trigger (or the similar code at the app level).
Using a view works too, but if you need it frequently you'll want it pre-calculated for performance reasons.
For an introduction to triggers, see:
http://dev.mysql.com/doc/refman/5.6/en/triggers.html
You probably want something like this:
CREATE TRIGGER character_sum_ins BEFORE INSERT ON character
FOR EACH ROW SET NEW.sum = NEW.strength + NEW.intelligence + NEW.skill;
CREATE TRIGGER character_sum_upd BEFORE UPDATE ON character
FOR EACH ROW SET NEW.sum = NEW.strength + NEW.intelligence + NEW.skill;
Alternatively, pre-calculate the sum in your app and store it accordingly.
Side note: ask yourself if you really need this stored though. As point out by another commenter, there might be no need for the auto-calculated data at all.
This should work, if I'm understanding your question correctly and the strength, intelligence, skill columns are numeric data types.
select strength, intelligence, skill, strength+intelligence+skill as sum
from character
As suggested, a view could then be created pretty easily with:
create view totals as
select strength, intelligence, skill, strength+intelligence+skill as sum
from character
You would want to make this into a stored procedure. The procedure could do the calculations, and you could read the results as though they were columns.
You could also probably get away with a simple view for this use case.
Don't do this in mysql, just add the values up when displaying them, seriously.
Or if you really want, sum them in mysql in your SELECT statement when returning them.
Don't use a trigger just to maintain a total of some numbers - they are a seriously screwy way of confusing all future develoeprs on the project.
Related
i have an SQL table that you can add brand names to, and when a new brand name is added, it will either increase the existing brand active count, or create a new brand name.
The problem is, if someone added a new brand with different spelling (like adding Toyota but spelled toyota) it would make a new brand with a new active count and new brand id. Now that the table has a few instances of this, is there a way i can sort through with SQL and merge the similar brands? I know this would end up deleting a few rows and I'm not sure if SQL has the power to do this all at once.
I'm still kind of new to SQL so any advice on this is appreciated. I heard that using Python Pandas would be easier so I am currently looking into that for a method to do this.
In case of simple case changes, you can use functions like LOWER() to convert all of them to lower case and then group results together based on brand_name,
However, your question says "similar" records where similar is not so well defined. The SQL language expects you to clearly define what you need.
If you are looking to fix one / few characters you can use LIKE operator with percentage (%) and / or underscore (_) sign. You can define all permutations of errors you would like to identify by placing % and _ at various positions. Alternatively, you can also explore SOUNDEX function or sounds like in MySQL and see if you can merge brand names based on SOUNDEX.
If data is not huge, I will suggest you to create another table / temporary table to perform such operation. This way, you can always refer back to original data.
I'm building a MySQL event to make a copy of a table in the database with a timestamp in the name.
CREATE TABLE `db_name`.`tbl_prefix_(SELECT TO_SECONDS(NOW()))` ( [the rest...]
Obviously this isn't working. What should I do to make it work?
Any suggestions are welcome.
Thanks
This is a bad architecture. Generating tables on the fly is not something you should do.
Instead, create a single table with a timestamp column. For instance, if you would before have 3 tables with three timestamps A, B, and C, you now have one table with a timestamp column containing the values A, B, and C, respectively.
In order to do this, you would need to use "dynamic SQL". That is, make use of the MySQL PREPARE statement.
What you'd need to do is populate a variable with a string that contains the SQL text you want to execute. Doing variable substitution into string is trivial.
The "trick" is to take that dynamic string and execute it like it was a SQL statement.
And that's what the PREPARE statement does for us, takes in a variable, and reads the contents of that variable like it were a SQL statement.
With that said, rather than give an example code that demonstrates this in more detail, I'm going to suggest that you re-think this idea of creating a table with timestamp value as part of the name.
What problem is that designed to solve? And carefully consider whether the proposed design for a solution will introduce a bigger problem than it solves.
I basically have results grid and i have a drop down menu on my application which filters the 'Carrier' column. But when selecting a certain carrier I want all the rows returned that have the same dr_id as the Carrier which has been selected.
For example if you look at the picture attached it shows my results grid. If I filter by carrier 'ACE CALL LTD_UK' then I want rows 27, 28, 29 and 30 returned because the dr_id is the same.
Thanks
I don't have a complete solution for you as I don't know exactly what you database schema is (and it is a large stored procedure!). However I do have some suggestions/comments which you might find helpful:
I assume that the stored procedure will currently be returning a single row when they filter is set to 'ACE CALL LTD_UK', if not then this might not be relevant!
What I would do in this case would be to take you SELECT statement and put the results into a CTE, temporary table or nested query. (I'm not sure what SQL DBMS your using, looks like MSSQL, but you also have a MySQL tag for you post).
Once I have those results I would then use a LEFT JOIN from the dr_id in the temp table back to the drm table on the same column. From here you will again need to join to other tables where the data is not distinct, for example the Carrier table, then select the columns that you require.
You could do all this in the existing SELECT statement, however you will have to start joining on tables multiple times or use nested queries, which would get very messy. However the main reason why I chose the solution I have posted is because I don't know the stored procedure well enough and therefore I chose the safest solution.
If you want an example of what I mean, I will try and provide one.
I'd like to select * from 2 tables, but have each table's column name be prefixed with a string, to avoid duplicate column name collissions.
For example, I'd like to have a view like so:
CREATE VIEW view_user_info as (
SELECT
u.*,
ux.*
FROM
user u,
user_ex ux
);
where the results all had each column prefixed with the name of the table:
e.g.
user_ID
user_EMAIL
user_ex_ID
user_ex_TITLE
user_ex_SIN
etc.
I've put a sql fiddle here that has the concept, but not the correct syntax of course (if it's even possible).
I'm using MySql, but would welcome generic solutions if they exist!
EDIT: I am aware that I could alias each of the fields, as mentioned in one of the comments. That's what I'm currently doing, but I find at the start of a project I keep having to sync up my tables and views as they change. I like the views to have everything in them from each table, and then I manually select out what I need. Kind of a lazy approach, but this would allow me to iterate quicker, and only optimize when it's needed.
I find at the start of a project I keep having to sync up my tables and views as they change.
Since the thing you're trying to do is not really supported by standard SQL, and you keep modifying database structures in development, I wonder if your best approach would be to write a little script that recreates that SELECT statement for you. Maybe wrap it in a method call in the development language of your choice?
Essentially you'd need to query INFORMATION_SCHEMA for the tables and columns of interest, probably via a join, and write the results out in SQL style.
Then just run the script every time you make database structural changes that are important to you, and watch your code magically keep up.
Need to intelligently perform updates on an access table.
Expert VBA / Intelligent Thinking would be required.
Table1 (For reference only)
CompanyCode Text
RegionCategory Number (1-99)
RegionCount Number(0 - 25000)
Table2
InvoiceNumber Number
CompanyCode Text
NumRows Number
RegionCode FourdigitNumber
ConfirmationRemark Y / N
Ourobjective is to put a Yes or No in the 'ConfirmationRemark' Column.
Rules :
1.Select only those InvoiceNumbers which have exactly two rows from Table2 and different RegionCode. These will have the same CompanyCode. RegionCategory is first two digits of RegionCode.
2.For these two Invoices - The difference between the two RegionCategory must be greater than two.
3.LookUp The RegionCount , from Table1
Decision Making :
We are now basically comparing two Invoices with different RegionCodes.
Idea is that , the Invoice with higher RegionCount is the one to be marked Yes.
1.The difference between RegionCount must be considerable. 'considerable' - I am trying to determine what would be the right number. Let us take 500 for now.
2.The Invoice with lower Region Count - should have RegionCount - Zero (bestCase) or very very low. If The Invoice with lower Region Count has a high RegionCount value > 200 , then we cannot successfully conclude.
3.NumRows , is prefered to be 1 or lesser than the other. This comparison , is not mandatory , hence we shall have a provision to not check for this. Mark the Other Invoice as 'N'
You have many ways to approach that type of complex update.
If you are lucky, you may be able to craft a SQL UPDATE statement that can include all the changes, but often you will have to resort to a combination of SELECT queries and custom VBA to filter them based on the results of calculations or lookups involving other data.
A few hints
Often, we tend to think about a problem in terms of 'what are the steps to get to the data that match the criteria'.
Sometimes, though, it's easier to turn the problem on its head and instead ask yourself 'what are the steps to get to the data that do not match the criteria'.
Because in your case the result is boolean, true or false, you could simply set the ConfirmationRemark field to True for all records and then update those that should be set to False, instead of the other way around.
Break down each step (as you did) and try to find the simplest SELECT query that will return just the data you need for that step. If a step is too complex, break it down further.
Compose your broken down SELECT statements together to slowly build a more complex query that tends toward your goal.
Once you have gone as far as you can, either construct an UPDATE Table2 SET ConfirmationRemark=True WHERE InvoiceNumber IN (SELECT InvoiceNumber ....) or use VBA to go through the recordset of results from your complext SELECT statement and do some more checks before you update the field in code.
Some issues
Unfortunately, despite your efforts to document your situation, there are not enough details for us to really help:
you do not mention which are the primary keys (from what you say, it seems that Table2 could have multiple records with identical InvoiceNumber)
the type of data you are dealing with is not obvious. You should include a sample of data and identify which ones should end-up with ConfirmationRemark set.
your problem is really too localised, meaning it is too specific to your to be of value to anyone else, although I think that with a bit more details your question could be of interest, if only to show an example of how to approach complex data updates in Access.