Update table column wiht unique string using where exist statment - mysql

I have unique column url varchar(4), and want to update it to unique random string, but having problems with duplicated items.
So I want to create loop something like this, but having problem with targeting twice same table.
UPDATE IGNORE word SET url = (SELECT GROUP_CONCAT(SUBSTRING('1234567890qwertyuiopasdfghjklzxcvbnm' , 1+ FLOOR(RAND()*LENGTH('1234567890qwertyuiopasdfghjklzxcvbnm')) ,1) SEPARATOR '')
FROM (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS dummy_tbl)
WHERE EXISTS (SELECT url FROM word WHERE url IS NULL);
What is the best way to fill my column, with single query?

You should remove the EXISTS clause and just update the NULL rows directly:
UPDATE
IGNORE word
SET url = ...
WHERE url IS NULL;
So your full query would be:
UPDATE
IGNORE word
SET url =
(SELECT GROUP_CONCAT(SUBSTRING('1234567890qwertyuiopasdfghjklzxcvbnm',
1+ FLOOR(RAND()*LENGTH('1234567890qwertyuiopasdfghjklzxcvbnm')),1) SEPARATOR '')
FROM
(SELECT 1
UNION SELECT 2
UNION SELECT 3
UNION SELECT 4) AS dummy_tbl)
WHERE url IS NULL;

Related

How to SQL select excluding strings with N duplicate characters in a row

How to make a select from a table excluding rows with N duplicate characters in a row in a certain column? Let's say N=5
'0000011114BR13471' // Exclude
'554XXXXXXXXXXXXXX' // Exclude
'000111114BR134716' // Exclude
'000011114BR134716' // Include
'11880000000000000' // Exclude
'12345678901200000' // Exclude
'12345678901200001' // Include
I tried many combinations but none of them worked. For example:
SELECT * FROM mytable WHERE not (mycolumn regexp '(.)\1{5,}');
Thank you!
You can use the LIKE to match regular Expression and EXCEPT clause to exclude unwanted Results. A query like this might work
In SQL SERVER
Select * from myTable
EXCEPT
Select * from myTable WHERE ColumnName like '(.)\1{4,}'
In MySQl
Select * from myTable
where ColumnName Not In(
Select ColumnName from myTable WHERE ColumnName RLIKE '(.)\1{4,}')
Here N=5. the 4 in regular expration represents 5 duplicates.
I don't think MySQL supports back-references in regular expressions -- which is a shame for your problem. One method is brute force:
select t.*
from t
where col not regexp '0{5}|1{5}|2{5}|3{5}|4{5}|5{5}|6{5}|7{5}|8{5}|9{5}|X{5}';
Another method is a recursive CTE, which breaks up the string into individual characters and then uses window functions to determine if there are 5 in a row:
with recursive cte as (
select col,left(col, 1) as chr, substr(col, 2) as rest, 1 as lev
from t
union all
select col, left(rest, 1), substr(rest, 2), lev + 1
from cte
where rest <> ''
)
select col
from (select cte.*,
lead(lev, 4) over (partition by col, chr order by lev) as chr_4
from cte
) x
group by col
having max(chr_4 = lev + 4) = 0
Here is a db<>fiddle.
In MySQL 8.0:
mycolumn regexp '(.)\\1{4}'
Notes:
Two backslashes are needed.
Since there is 1 selected (.), you need to check for only 4 more, not 5.
The , (meaning "or more") is unnecessary.

MySQL How to split string from column by " " and insert result separated by , into another column?

I would like to ask how to split string from column (all rows in table) by " " and insert result separated by , into another column in same table?
Many thanks for any advice.
Table struct example:
------------------------------------------
| Original string | Spliced string |
------------------------------------------
| Some string 001 | Some,String,001 |
------------------------------------------
If I needed to "split" a string on a delimiter, I'd likely make use of the nifty SUBSTRING_INDEX function. But there are a few quirks to be aware of.
The approach I would take would certainly be to write a SELECT statement first. That would include the expression(s) in the SELECT list that return the "separated" values that I wanted to assign to another column. I'd get those expressions tested using a SELECT statement, before I wrote an UPDATE statement.
SELECT t.id
, t.column_i_want_to_split
, expr1
FROM mytable t
ORDER BY t.id
To test specific cases, I'd make use of an inline view
SELECT t.id
, t.note
, t.val
, expr1
FROM ( SELECT 1 AS id, 'empty string test' AS note, '' AS val
UNION ALL SELECT 2, 'null', NULL
UNION ALL SELECT 3, 'one space', ' '
UNION ALL SELECT 4, 'four spaces', ' '
UNION ALL SELECT 5, 'test5', ' abc def '
UNION ALL SELECT 6, 'test6', 'g hi kl m'
) t
ORDER BY t.id
Once I had the expression(s) returning the values I want to assign to another column, I'd convert the SELECT into an UPDATE statement. To process all rows, omit the WHERE clause.
UPDATE mytable t
SET t.another_column = expr1
Without a more definitive specification, or at least some concrete examples of what you are attempting to achieve, we're just guessing. Given only a general description of the problem, all we can offer is some general advice.

DISTINCT and CONCAT togheter

I need to create unique SEO words for website by adding - to distinct words.
I tried query
UPDATE url_alias SET `keyword = (SELECT DISTINCT CONCAT( keyword, '-' ));
but this query adds - to all words. What is wrong with this query?
Example: Words are Acer, Acer, Acer-, Apple, Apple, Apple- and these should be finally Acer, Acer-, Acer--, Apple, Apple-, Apple--
Table example in here.
UPDATE url_alias SET `keyword` = `keyword` + '-'
I need to create unique SEO words for website by adding - to distinct
words. ...
but this query adds - to all words. What is wrong with this query?
You can use a WHERE condition to filter and set values to specific occurrences.
Example:
UPDATE url_alias SET keyword = CONCAT( keyword, '-' )
where keyword = ?
Change the where condition as desired to match an occurrence and execute.
Try this
UPDATE url_alias U1 SET keyword =
(SELECT CONCAT( keyword, '-' ) from url_alias group by keyword) U2
where U2.id=U1.id;
Try with:
CREATE TEMPORARY TABLE TSEL SELECT keyword FROM url_alias GROUP BY keyword HAVING COUNT(keyword) = 1;
UPDATE url_alias SET keyword = CONCAT( keyword, '-' ) WHERE keyword IN (SELECT keyword FROM TSEL);
This is:
Create a temporary table containing all unique keywords: This is, they are not repeated at different rows.
Updating those keywords contained in TSEL.
TSEL will be automatically deleted when your session is finished. Nevertheless you can delete it explicitly using:
DROP TABLE TSEL;
EDIT
If you want to ignore case as well as already inserted '-' characters, you will have to normalize keyword when the time to calculate candidates to update comes. In this case, your new SQLs should be:
CREATE TEMPORARY TABLE TSEL SELECT UCASE(TRIM( BOTH '-' FROM keyword)) AS keyword FROM url_alias GROUP BY UCASE(TRIM( BOTH '-' FROM keyword)) HAVING COUNT(1) = 1;
UPDATE url_alias SET keyword = CONCAT( keyword, '-' ) WHERE UCASE(TRIM( BOTH '-' FROM keyword)) IN (SELECT keyword FROM TSEL);
If you consider "Acer" and "Acer-" as different:
CREATE TABLE TSEL SELECT UCASE(keyword) AS keyword FROM url_alias GROUP BY UCASE(keyword) HAVING COUNT(1) = 1;
UPDATE url_alias SET keyword = CONCAT( keyword, '-' ) WHERE UCASE(keyword) IN (SELECT keyword FROM TSEL);

Select row by using one distinct column

I have one table named dictionarydefinition.
CREATE TABLE dictionarydefinition (
id bigint NOT NULL,
definition character varying(1024) NOT NULL,
word character varying(200) NOT NULL,
grammertypename character varying(20) NOT NULL,
)
I have sql command Select * from dictionarydefinition where word like 'someword%'.
Results are multiple rows that got same value. For example if someword% is just empty ''
the result will be:
A
A
A
B
B
C
D
D
D
I just want result be:
A
B
C
D
I have used GROUP BY command, but it takes too much time to process 30MB database for my android device.
What kind of SQL commands I can add to make it choose only one row which got someword% value?
For the example you have mentioned, you can use GROUP BY.. Suppose the column-name for the alphabets is word, the command would be :
SELECT * from dictionarydefinition where word like 'someword%' GROUP BY word;
You can use SELECT TOP or LIMIT or ROWNUM
SELECT TOP 1 * from dictionarydefinition where word like 'someword%';
or
SELECT * from dictionarydefinition where word like 'someword%' LIMIT 1;
or
SELECT * from dictionarydefinition where word like 'someword%' AND ROWNUM <= 3

How to select all columns in sql except one column? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
SQL exclude a column using SELECT * [except columnA] FROM tableA?
Is selecting all columns except one column possible??
here is all column names: id, name, address, age
SELECT id, name, address from TBLUser
I don't want to use this select statement because the number of columns of my tables are different to each other.
declare #cols varchar(max), #sql varchar(max)
SELECT #cols = STUFF
(
(
SELECT DISTINCT '], [' + name
FROM sys.columns
where object_id = (
select top 1 object_id from sys.objects
where name = 'TBLUser'
)
and name not in ('age')
FOR XML PATH('')
), 1, 2, ''
) + ']'
select #sql = 'select ' + #cols + ' from TBLUser'
exec (#sql)
How about:
SELECT * FROM sys.columns
WHERE Name <> N'Column To Exclude' and Object_ID = Object_ID(N'TBLUser')
This will return all columns except the one you wish to exclude.
Expanded explanation:
According to this explanation from SQL Cheat Sheet
sys.columns is a system table and is used for maintaining information on columns in a database. For every column added in database, a record is created in the sys.columns table. There is only one record for each column
Name: The name of the column. This is unique within the table object.
Object_id:object_id is unique identifier for table in which the column exists. We will use this column to join sys.columns with sys.tables in order to fetch columns in different tables.
We are selecting all results from sys.columns where the name is not equal to whatever you provide, replace 'Column To Exclude' with your column name. We are also requiring that the object_id equal the object_id you provide. object_id is a number that represents the table you want to filter out the one column from. In this ops case the table was TBLUser, in other uses it would be like this object_id(N'[dbo].[YourTable]'), you would replace [YourTable] with your own table name
in sql*plus,
the one way is to disable as follows:
sql> column age noprint
sql> SELECT * from TBLUser
then, you can revert using
sql>column age off
or else you've to user dynamically with DBMS_SQL package.