I have a concatenated string in a field that I now need to pull statistics from.
What is needed is a count of how many records are from each county in Maryland.
fieldname county_city is stored as follows:
Frederick,MD - Frederick County - 21701
//State
trim(substring(SUBSTRING_INDEX(county_city,',',-1),1,3)) as state
//city
SUBSTRING_INDEX(county_city,'-',1) as city_state
//zip code
SUBSTRING_INDEX(county_city,'-',-1) as zipcode,
but getting the county has been eluding me!
I have an idea that getting the count will elude me as well.
With string functions is a 2 step procedure:
set #s = 'Frederick,MD - Frederick County - 21701';
SELECT TRIM(SUBSTRING_INDEX(SUBSTRING(#s, LENGTH(SUBSTRING_INDEX(#s, '-' ,1)) + 2), '-', 1));
See the demo.
Result:
Frederick County
Related
I have 1 table called BSFolks that contains:
Name Number
---- ------
Sam Jackson BS001
Sam Jackson BS003
Sam Jackson null
Miley Cyrus BS666
Miley Cyrus BS069
Miley Cyrus BS013
C. Agulera BS420
And would like to return
Name Number
---- ------
Sam Jackson BS001,BS003
Miley Cyrus BS666,BS069,BS013
C. Agulera BS420
I've been having a hard time finding the correct search terms for this operation so please excuse me if this has already been answered.
I am using SQL Server 2008 BTW.
Thanks y'all!
EDIT:
Here's the solution.
SELECT Name, STUFF((SELECT DISTINCT ',' + Number FROM BSFolks
WHERE Name = X.Name
AND (Number != '' AND Number IS NOT NULL)
FOR XML PATH ('')), 1, 1, '') AS Numbers
FROM BSFolks X
GROUP BY Name
SELECT Name, STUFF((SELECT DISTINCT ',' + Number FROM BSFolks
WHERE Name = X.Name
AND (Number != '' AND Number IS NOT NULL)
FOR XML PATH ('')), 1, 1, '') AS Numbers
FROM BSFolks X
GROUP BY Name
I'm attempting the following problem:
The capital of Mexico is Mexico City. Show all the countries where the capital has the country together with the word "City".
Find the country where the capital is the country plus "City".
And I was wondering why this query is correct:
SELECT name
FROM world
WHERE capital = CONCAT (name, ' city');
And yet this one isn't:
SELECT name
FROM world
WHERE capital = CONCAT (name, 'city');
Why does this instance of the CONCAT function require a space before 'city'?
The second entry would match only if the capital of the country was for example Mexicocity.
as it is concatenating the name with city like 'name' + 'city' = 'mexicocity' this won't match 'mexico city'
What is there to wonder about? spaces are part of a string, your string is "Mexico City", your name column is just "Mexico", if you concat "City" into it you get "MexicoCity" not "Mexico City".
Why does this instance of the concat function require a space before 'city'?
It's because there is literally a space between the capital name. You are concatenating a string with a ' ' + [city].
CONCAT takes a variable number of string arguments and concatenates them into a single string. It requires a minimum of two input values; otherwise, an error is raised. All arguments are implicitly converted to string types and then concatenated.
For instance, consider this test data (you can test it here)
;WITH world (country, capital) AS (
SELECT 'Mexico','Mexico City' UNION ALL
SELECT 'Guatemala','Guatemala City' UNION ALL
SELECT 'Panama','Panama City' UNION ALL
SELECT 'South Korea','Seoul' UNION ALL
SELECT 'Vatican City','Vatican City'
)
--verify
--Mexico (Mexico City)
--Guatemala (Guatemala City)
--Panama (Panama City)
--NOT return Vatican City because 'Vatican City' <> 'Vatican City City'
SELECT *
FROM world
WHERE capital = CONCAT(country, ' City')
If you check properly there is space in the capital between name and city so the following query is not working
SELECT name FROM world WHERE capital = concat(name, 'city');
So you should either remove space from capital using replace or add space in the name and city as below
SELECT name FROM world WHERE replace(capital, ' ', '') = concat(name, 'city'); --return value
Or
SELECT name FROM world WHERE capital = concat(name, ' city'); --return value
Or
SELECT name FROM world WHERE capital = concat(name, ' ', 'city'); --return value
I am a beginner of the SQL language and wonder a little about how I can match names from my database that has the same first letter in
first- and lastname ?
For exemple:
Alex Andersen
Alice Aaronson
Brad Baalman
Brett Baren
Chris Cat
And so forth...
My code is:
SELECT substring(firstname,1) AS first_letter
AND substring(lastname,1) AS first_letter
FROM kids
ORDER BY firstname
Use WHERE to filter records:
SELECT *
FROM kids
WHERE LEFT(firstname, 1) = LEFT(lastname, 1)
ORDER BY firstname;
or:
SELECT *
FROM kids
WHERE SUBSTRING(firstname, 1, 1) = SUBSTRING(lastname, 1, 1)
ORDER BY firstname;
I have an InnoDB table with fields
firstname, lastname
While displaying names, usually only firstname is enough. Sometimes users have the same first name; so I have to get firstname and first letter of lastname:
CONCAT(firstname, ' ', SUBSTRING(lastname, 1, 1), '.')
Is there a (performant) way to only display the first letter of the last name in case of a double first name? Something like
WHEN isDouble(Firstname) THEN
CONCAT(firstname, ' ', SUBSTRING(lastname, 1, 1), '.')
ELSE firstname
/* edit */
Forgot to mention the solution I was thinking of:
Creating a column 'double_firstname', with value 1 or 0, and use a CASE statement to select. Then update the double_firstname column on user create and delete.
You can of course ask mysql if the number of entries for that firstname is bigger than one, so:
select IF( (select count(*) as cnt from person where firstname = p.firstname) > 1
, concat(firstname, " ", substring(lastname, 1))
, firstname)
from person
where id = 4711
;
But that is not very quick.
Better for a higher number of persons is a stable mark on person how to "call" her. That could be "firstname lastname" initially and then get more personally with reducing to firstname by a cronjob. It also could mean to call "John Doe" just John, because he entered early, and "John DaSecond" call "John D.", and "JohnDaThird" call "John DaT.".
JohnD is not unique in that scenario.
Is John Doe informed about being renamed to "John D." in your Scenario?
You asked for good performance as well as the ability to do it. If you have an index on names(firstname, lastname) the following should perform well:
select (case when exists (select 1
from names n2
where n2.firstname = n.firstname and n2.lastname <> n.lastname
)
then concat(firstname, ' ', left(lastname, 1))
else firstname
end)
from names n
How can I replace the last occurrence of a substring with blank string in MYSQL?I could not find any such direct function in MYSQL
String: "American Corp National Corp"
Search String: "Corp"
Expected output: "American Corp National"
Could anyone suggest?
This is shorter and more readable:
SELECT TRIM(TRAILING 'Corp' FROM 'American Corp National Corp')
Try:
select reverse(concat(
left(reverse('American Corp National Corp'),
instr(reverse('American Corp National Corp'),reverse('Corp'))-1),
substr(reverse('American Corp National Corp'),
instr(reverse('American Corp National Corp'),reverse('Corp'))+
length('Corp')))) result
(SQLFiddle)
After researching this problem myself and reading the answers above, I created the following function to solve this problem. In my case, I needed to change the last separator in a sequence, so that e.g., "Aap, Noot, Mies" would become "Aap, Noot & Mies":
CREATE DEFINER=`root`#`localhost` FUNCTION `change_last_substring`(
input_string text,
separator_old tinytext,
separator_new tinytext
) RETURNS text CHARSET utf8
BEGIN
set #output_string=
trim(
leading separator_new from
concat
(
left(input_string,length(input_string)-length(substring_index(input_string,separator_old,-1))-2),
separator_new,
substring_index(input_string,separator_old,-1)
)
);
RETURN #output_string;
END
Here is an SQL-query:
select CONCAT(SUBSTRING_INDEX('<TEST_STRING>','<String that you want to replace>',(length('<TEST_STRING>') - length(replace('<TEST_STRING>', '<String that you want to replace>', '')))),'<String to be replaced>',SUBSTRING_INDEX('<TEST_STRING>', '<String that you want to replace>', -1)) as test
This feels like an awful way to do it, but... reverse the string, search for the first occurence of the reverse of the search string using locate, then calculate what index that would be in the non reversed string?
http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_reverse
http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_locate
http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_char-length (Pretty sure you need to use this instead of length to be unicode compliant, but check to be sure!)
Worked example:
String: 0123456789 (char_length = 10)
Search string: 567 (char_length = 3)
Reverse string: 9876543210
Reverse search string: 765
Locate returns index = 2
index of end in real string = 7 (char_length(string) - 1 - index -> 10 - 1 - 2)
index of start in real string = 5 (char_length(string) - 1 - (char_length(search string) - 1) - index -> 10 - 1 - (3 - 1) - 2)
The accepted answer doesn't replace #FROM with #TO, it replaces #FROM with empty string. If you need to replace #FROM with #TO, here is a modification of that answer:
SELECT reverse(
concat(
concat(
left(reverse(value),
instr(reverse(value), reverse(#FROM)) - 1),
#TO
),
substr(reverse(value),
instr(reverse(value), reverse(#FROM)) +
length(#FROM))))
FROM `table`
WHERE `value` like '%' + #FROM + '%'
Notice additional WHEREvaluelike '%' + #FROM + '%', as this removes an extra character if the substring doesn't occur in the value, e.g. trying to replace "a" with "b" in "ccc" results in "cc"
More easy and reliable
CONCAT(SUBSTRING_INDEX('American Corp National Corp','Corp',2), "REPLACE_STRING" ,SUBSTRING_INDEX('American Corp National Corp','Corp',-1))
REPLACE_STRING you can change it with replace string or empty for replacing.
If you have a recent version of MySQL (>= v8) / MariaDB (>= v10.0.5), you can use REGEXP_REPLACE to replace the last occurrence of needle with replacement, like so:
REGEXP_REPLACE(haystack, "^.*needle", "\\1replacement")
This exploits the greediness of *.
If you are using MySQL, and know (or can calculate) the number of occurrences, you can use the optional occurence parameter of REGEXP_REPLACE.