How to replace entire values in a specific column? - sql

I am trying to replace and entire value in a column (pet). The value ‘dog’ is repeated 85 times in that same column. If I wanted to replace it with ‘cat’ how would I do that but just in a that single column (pet)?
I tried with…
SELECT pet REPLACE(pet, ‘dog’, ‘cat’)
FROM Animals
Error message

REPLACE() in SQL will replace all instances of a specific sub-string within a string column value. But when used in a SELECT it only affects the output for that query, it will not update the source table.
The following should return all pets, and in the second column the dogs should be cats:
SELECT pet, REPLACE(pet, ‘dog’, ‘cat’) as newPet
FROM Animals
But REPLACE() is really designed for replacing 'dog' inside of a longer string, for instance to change thequickbrownfoxjumpsoverthelazydog to thequickbrownfoxjumpsoverthelazycat
It should still work for your simple scenario but it will change a dogfish into a catfish and that might not be appropriate.
The other way to do a conditional replacement is with CASE
SELECT pet
, CASE pet
WHEN ‘dog’ THEN ‘cat’
ELSE pet
END as newPet
FROM Animals
In these examples the replacement is shown as a separate column, just to demonstrate the output side-by-side with the source column, but you can use the column alias to return the calculated column instead of pet
SELECT CASE pet
WHEN ‘dog’ THEN ‘cat’
ELSE pet
END as pet
FROM Animals
If you want to permanently update the values in the source table, then combine either of these options with an UPDATE statement, the simplest form would be this
UPDATE Animals SET
pet = 'cat'
WHERE pet = 'dog'

Related

Create Table based on distinct attributes in SQL

I need to create a new table in MS Access based on a specific attribute. To simplify the problem, I will illustrate the desired result with a dummy table:
As you can see, I have different flowers (distinguished by their numbers - Flowerno), along with their attributes and values. The new table should be based on the distinct pairs of Attribute "color" and its Value. So in this example, we have two pairs: (color, red) and (color, yellow). Now, each pair belongs to a specific Flowerno and its other attributes like shape and fragrance. I would like to create a table with the attribute color as the main focus and present its other attributes of the same flower:
In other words, I want to list all colors along with the attributes and values distinctively in three different columns.
You need code that will do a lookup of color associated with flowerno and return that value for use in sorting/grouping. Could try calculating a field with DLookup:
GrpColor: DLookup("value", "table","attribute='color' AND flowerno=" & [flowerno])
Unfortunately, domain aggregate function can cause slow performance in query. Alternative would use subquery:
SELECT table.*, Q.GrpColor FROM table
INNER JOIN (SELECT FlowerNo, [Value] AS GrpColor
FROM table WHERE attribute = "color") AS Q
ON table.FlowerNo = Q.FlowerNo
WHERE Attribute<>"color";

How Do I Create A Procedure That Searches Data By Using a Value Typed By The User?

For example: I want to create a procedure with a Select statement the searches the info of an animal, where the user types in any animal name and the procedure searches for it.
If the user types "Dog", I want to get every data of "Dog" in my table. Same with Cat, Bird, etc.
use WHERE clause to filter the data in the table,
ex.
SELECT * FROM table WHERE animal = 'Dog'

SQL select statement dout

I have a table in which it contains the Name column contains some names in Capital letters and some data is in small letters in my WHERE clause if i give (where name='Syed') it will give only matching records because it is case sensitive but i want my output should display like(SYED,Syed,syed) how to do that please help me
SELECT Name
FROM Persons
WHERE UPPER(Name) = 'SYED'
This will return the Name in whatever case it exists as in the table, but will return all instances of it.

insert made instead of update resulting in duplicate rows. how to fix?

I have a database where is supposed to have only one register with 2 value columns that can be filled by my web application. The values to one of the columns where given to me in an excel and we had to put it into the database. The person who did that, should had used an "update if exists else insert" but he didn't. Now, we have for some data, duplicate lines, one having just the column "valor_realizado_oficial" filled (with the column adt_login filled with 'talend' and with the key columns filled too), and another with the other column filled by the application.
So:
If exists two lines, I would like to copy the value of the column "valor_realizado_oficial" from the line with adt_login like 'talend' to the other line and delete this line.
If exists just one line, do nothing.
I tried to perform the copy part with:
update indicador_val iv
set valor_realizado_oficial=carga.valor_realizado_oficial
from (
select valor_realizado_oficial, ano, municipio_fk, indicador_fk, und_federativa_fk
from indicador_val
where adt_login like 'talend' and ano=2013 ) carga
where iv.ano=2013 and iv.municipio_fk=carga.municipio_fk
and iv.indicador_fk=carga.indicador_fk and iv.ano=carga.ano
and iv.und_federativa_fk = carga.und_federativa_fk;
But 0 rows where affected. Here's an example of a pair of lines:
id; adt_login; ano; valor_estimado, valor_realizado_oficial, indicador_fk, municipio_fk, und_federativa_fk
313885; "talend";2013;;888;2;2202;
291998;"suagenda";2013;900;;2;2202;
And I would like to have just the second, with values:
291998;"suagenda";2013;900;888;2;2202;
What I did wrong? Thanks.
In the sample data, there are empty columns. For example, the last one: und_federativa_fk.
Some of these columns are used in your joining conditions in the correlated UPDATE. If these empty values translate to the SQL NULL value, you should realize that NULL=NULL as a condition is going to be NULL, which means false in this context.
That alone might explain why no row get updated.
The solution is to use IS NOT DISTINCT FROM as the comparison operator for values that may be null.
Example:
where iv.ano=2013 and iv.municipio_fk IS NOT DISTINCT FROM carga.municipio_fk
and iv.indicador_fk IS NOT DISTINCT FROM carga.indicador_fk
etc...

MySQL - Set default value for field as a string concatenation function

I have a table that looks a bit like this actors(forename, surname, stage_name);
I want to update stage_name to have a default value of
forename." ".surname
So that
insert into actors(forename, surname) values ('Stack', 'Overflow');
would produce the record
'Stack' 'Overflow' 'Stack Overflow'
Is this possible?
Thanks :)
MySQL does not support computed columns or expressions in the DEFAULT option of a column definition.
You can do this in a trigger (MySQL 5.0 or greater required):
CREATE TRIGGER format_stage_name
BEFORE INSERT ON actors
FOR EACH ROW
BEGIN
SET NEW.stage_name = CONCAT(NEW.forename, ' ', NEW.surname);
END
You may also want to create a similar trigger BEFORE UPDATE.
Watch out for NULL in forename and surname, because concat of a NULL with any other string produces a NULL. Use COALESCE() on each column or on the concatenated string as appropriate.
edit: The following example sets stage_name only if it's NULL. Otherwise you can specify the stage_name in your INSERT statement, and it'll be preserved.
CREATE TRIGGER format_stage_name
BEFORE INSERT ON actors
FOR EACH ROW
BEGIN
IF (NEW.stage_name IS NULL) THEN
SET NEW.stage_name = CONCAT(NEW.forename, ' ', NEW.surname);
END IF;
END
According to 10.1.4. Data Type Default Values no, you can't do that. You can only use a constant or CURRENT_TIMESTAMP.
OTOH if you're pretty up-to-date, you could probably use a trigger to accomplish the same thing.
My first thought is if you have the two values in other fields what is the compelling need for redundantly storing them in a third field? It flies in the face of normalization and efficiency.
If you simply want to store the concatenated value then you can simply create a view (or IMSNHO even better a stored procedure) that concatenates the values into a pseudo actor field and perform your reads from the view/sproc instead of the table directly.
If you absolutely must store the concatenated value you could handle this in two ways:
1) Use a stored procedure to do your inserts instead of straight SQL. This way you can receive the values and construct a value for the field you wish to populate then build the insert statement including a concatenated value for the actors field.
2) So I don't draw too many flames, treat this suggestion with kid gloves. Use only as a last resort. You could hack this behavior by adding a trigger to build the value if it is left null. Generally, triggers are not good. They add unseen cost and interactions to fairly simple interactions. You can, though, use the CREATE TRIGGER to update the actors field after a record is inserted or updated. Here is the reference page.
As of MySQL 8.0.13, you can use DEFAULT clause for a column which can be a literal constant or an expression.
If you want to use an expression then, simply enclose the required expression within parentheses.
(concat(forename," ",surname))
There are two ways to accomplish what you are trying to do as per my knowledge:
(important: consider backing up your table first before running below queries)
1- Drop the column "stage_name" all together and create a new one with DEFAULT constraint.
ALTER TABLE actors ADD COLUMN stage_name VARCHAR(20) DEFAULT (concat(forename," ",surname))
2- This will update newer entries in the column "stage_name" but not the old ones.
ALTER TABLE actors alter stage_name set DEFAULT (concat(forename," ",surname));
After that, if you need to update the previous values in the column "stage_name" then simply run:
UPDATE actors SET stage_name=(concat(forename," ",surname));
I believe this should solve your problem.