How to duplicate a column to a list of comma delimited items in SQL - mysql

I am trying to figure out how to append the id to each item in the tags list. For example I have a item id of 01 and its corresponding tags are Recycled, leather, case, holder, iPad, snap, kindle. I am trying to figure out how to output the data in a way that it can be exported from mySQL line by line.
01;Recycled
01;leather
01;case
01;.....
02;agrarian
02;urban
id tags
01 Recycled, leather, case, holder, iPad, snap, kindle
02 agrarian, urban, planter, eco, ...
I have tried pulling the id into a table, I have tried using substring to parse the data, but I just can't figure out how to get the data the way I am looking for.
Thank you for your help

I am guessing that you want group_concat():
select id, group_concat(tag separator ', ') as tags
from t
group by id;

Related

How to select one value of MySQL JSON array

I am trying to display everything that contains zbs tag2 from a JSON format that is in my MariaDB see screen.
So my query to add the values is owner varhcarm picture TEXT and tags JSON:
INSERT INTO json_pics(owner, picture, tags) VALUES ("test", "test.png",'["tag3", "tag4"]');
I'm trying to display all entries that have e.g. "tag4" in field tags with a SELECT statement as mentioned above. So that I can filter for one of the things in the brackets. This should work with JSON_CONTAINS or something like that? Image from the example DB: enter image description here
Now id 2 and 3 should be displayed because they both have tag 4 :)
Thanks in advance and many greetings, Flo
I'm trying to display all entries that have e.g. "tag4" in field tags with a SELECT statement
SELECT *
FROM json_pics
WHERE JSON_CONTAINS(tags, '"tag4"');

How do you use REGEX to extract key => values from JSON with unknown levels of nesting?

I am trying to use regex to extract UPCs from a JSON list, but each UPC is deeply nested. Below is a sample.
{"offerId":78352,"tierLevel":null}],"offersEligibleForYourPrice":[]},"pointsEarned":null,"kcEarned":null,"lowestApplicablePrice":16.32},"availability":"In Stock","giftWrappable":false,"specialTypeSku":"N","isBopusEligible":true,"storeInfo":null,"sortOrder":"245000000026","itemMaxAllowedCount":99,"itemMaxAvailableCount":231,"maxQuantityMessage":"You can only purchase 99 of this item. Please select a lower amount and try again","shippingServiceCode":"4","isStoreAvailable":true,"surcharge":null,"sizeRange":"Regular","isBossEligible":true,"UPC":{"image":null,"ID":"889799687018"},"size2":"5T"},{"skuCode":"28960347","images":[{"url":"https://media.kohlsimg.com/is/image/kohls/3747263?wid=350&hei=350&op_sharpen=1","height":"350","width":"350","altText":"Toddler Girl's Disney's Minnie Mouse & Daisy Top & Bottom Set"}],"color":"Multi","size":"2T","price":{"isSuppressed":false,"salePriceStatus":"Sale","salePrice":{"minPrice":24,"maxPrice":null},"regularPriceType":"Regular","regularPrice":{"minPrice":40,"maxPrice":null},"promotion":{"tieredPrice":null,"group":null,"bogo":null},"suppressedPricingText":null,"yourPriceInfo":{"yourPrice":16.32,"yourPriceSavings":7.68,"appliedOffers":[77619,78352],"saveMoreOffers":[],"offersIncludedInYourPrice":[{"offerId":77619,"tierLevel":null},{"offerId":78352,"tierLevel":null}],"offersEligibleForYourPrice":[]},"pointsEarned":null,"kcEarned":null,"lowestApplicablePrice":16.32},"availability":"In Stock","giftWrappable":false,"specialTypeSku":"N","isBopusEligible":true,"storeInfo":null,"sortOrder":"245000000078","itemMaxAllowedCount":99,"itemMaxAvailableCount":483,"maxQuantityMessage":"You can only purchase 99 of this item. Please select a lower amount and try again","shippingServiceCode":"4","isStoreAvailable":true,"surcharge":null,"sizeRange":"Regular","isBossEligible":true,"UPC":{"image":null,"ID":"889799686981"},"size2":"2T"},{"skuCode":"28960348","images":[{"url":"https://media.kohlsimg.com/is/image/kohls/3747263?wid=350&hei=350&op_sharpen=1","height":"350","width":"350","altText":"Toddler Girl's Disney's Minnie Mouse & Daisy Top & Bottom Set"}],"color":"Multi","size":"3T","price":{"isSuppressed":false,"salePriceStatus":"Sale","salePrice":{"minPrice":24,"maxPrice":null},"regularPriceType":"Regular","regularPrice":{"minPrice":40,"maxPrice":null},"promotion":{"tieredPrice":null,"group":null,"bogo":null},"suppressedPricingText":null,"yourPriceInfo":{"yourPrice":16.32,"yourPriceSavings":7.68,"appliedOffers":[77619,78352],"saveMoreOffers":[],"offersIncludedInYourPrice":[{"offerId":77619,"tierLevel":null},
Using this regex
("UPC":)*("ID":")\w{12}
I get this result
"ID":"889799686981
How can this be improved to grab the ID from the UPC array?
The term ("UPC":)* is not part of your match - the quantifier * only matches for a quantity of zero.
I think you want:
"UPC":[^}]+"ID":"\w{12}
See live demo.
This will only match the ID of a UPC, due to the term [^}] which won't allow a } character between UPC and ID, thus tying the to together.

MySQL, select * while replacing text in certain column (before output)

I have a table with some 'HTML code' in one of the columns.. (an iframe/embed code to be exact)
We have a little 'table viewer' app here at work.. and when I go to the table and select * on it.. it parse the results in a table. (hence rendering the iframe/embed code) --- YUK! (and it takes forever to load)
How can I do a SELECT (not update/not permanent) statement on this table while selection ALL.. but also replacing some of the text in this embed column?
My goal/thought is to select *, replace the text 'iframe' to be 'xframe' or something.. so I only get the 'TEXT' in that column.. (and it doesnt parse in the table/display view)
I have tried slight variations of this: (didnt work)
SELECT * REPLACE('mp3_title', 'iframe', 'xframe') FROM table_name;
I tried this as well (mp3_new col was empty)
SELECT id, topic, title, vimeo_id, video_length, speaker_first, speaker_last, speaker_designation, description, active, replace(mp3_title, 'iframe','xframe') as mp3_new
FROM table_name;
update:
I apologize for my rush to post..
seems it was working. but I wasnt thinking enough to replace the < > brackets!!
this works fine:
SELECT id, topic, title, vimeo_id, video_length, speaker_first, speaker_last, speaker_designation, description, active, replace(mp3_title, '<iframe','^iframe') as mp3_new
FROM table_name;
Your first try should work fine - probably just a syntax error
Use
SELECT *, REPLACE(mp3_title, 'iframe', 'xframe') AS new_title FROM vimeo_videos;
Explanation:
remove quotes around fieldname, add comma after * to separate fields

Working Around SQL Replace Wildcards

I know that I cannot use a wildcard in a MySQL replace query through phpMyAdmin. But, I need some kind of workaround. I'm very open to ideas. Here's the skinny:
I have about 2,000 pages in a MySQL database that need to have image URL's updated. Some are local, some are hotlinked. Each one is different, the URL lengths vary, the image on the page and the new image are unique per page id number, and each one occurs at a different spot in the page.
I basically need to do the following:
UPDATE pages SET body = replace(body, 'src=\"%\"', 'src=\"http://newdomain/newimage.jpg\"') WHERE id="{page_number}"
But I know that the 'src=\"%\"' component doesn't jive.
So I fall at the feet of your collective knowledge to come up with some way to take the src="%" and replace it with a set URL for a set page id number. Thanks in advance.
If there's only one image per page, a quick solution would be like this:
UPDATE pages
SET
body = CONCAT(
SUBSTRING_INDEX(body, 'src="', 1),
'src=\"http://newdomain/newimage.jpg\"',
SUBSTRING(
SUBSTRING_INDEX(body, 'src="', -1)
FROM LOCATE('"', SUBSTRING_INDEX(body, 'src="', -1))+1)
)
WHERE
id="{page_number}" AND
body NOT LIKE '%<img%<img%';
First SUBSTRING_INDEX extract the body part at the left of src=", the last two nested SUBSTRING_INDEX extracts the body part at the right of the first " next to src=".
Last check is a very dirty check to make sure that only one image is present in the string. It could fail under some circumstances, but it might help.
My suggestion would be to build a table with your replace strings that would look like this:
page_id replace
1 src="..."
Then you can update across a JOIN like this
UPDATE pages AS p
INNER JOIN replace AS r
ON p.page_id = r.page_id
SET p.body = REPLACE(p.body, CONCAT('src="', SUBSTRING_INDEX(SUBSTRING_INDEX(p.body, 'src="', -1), '"', 1), '"', r.replace);
This would replace the last occurrence anything of format src="..." with a new value in same format, so this would work for all records with a single src value.

SQL query - Replace/Move some parts of content

I need to update about 2000 records in MySQL
I have a column 'my_content' from table 'my_table' with the folowing value
Title: some title here<br />Author: John Smith<br />Size: 2MB<br />
I have created 3 new columns (my_title, my_author and my_size) and now I need to separate the content of 'my_content' like this
'my_title'
some title here
'my_author'
John Smith
'my_size'
2MB
As you can imagine the title, author and size are always different for each row.
What I'm thinking is to query the following, but I'm not great at SQL queries and I'm not sure what the actually query would look like.
This is what I'm trying to do:
Within 'my_content' find everything that starts with "title:..." and ends with "...<br />au" and move it to 'my_title'
Within 'my_content' find everything that starts with "thor:..." and ends with "...<br />s" and move it to 'my_author'
Within 'my_content' find everything that starts with "ize:..." and ends with "...<br />" and move it to 'my_size'
I just don't know how to write a query to do this.
Once all the content is in the new columns, I can just find and delete the content that's not needed any more, for example 'thor:' , etc.
You can use INSTR to find the index of your delimiters and SUBSTRING to select out the part you want. So, for instance, the author would be
SUBSTR(my_content,
INSTR(my_content, "Author: ") + 8,
INSTR(my_content, "Size: ") - INSTR(my_content, "Author: ") - 8)
You'd need a bit more work to trim the <br/> and any surrounding whitespace.
Please try the below:
SELECT SUBSTRING(SUBSTRING_INDEX(mycontent,'<br />',1),LOCATE('Title: ',mycontent)+7) as mytitle,
SUBSTRING(SUBSTRING_INDEX(mycontent,'<br />',2),LOCATE('Author: ',mycontent)+8) as myauthor,
SUBSTRING(SUBSTRING_INDEX(mycontent,'<br />',3),LOCATE('Size: ',mycontent)+6) as mysize
FROM mytable;