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
Related
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
My 'name' column has names stored like this
Lastname Firstname Middlename
I want to display it like this in my query:
Firstname Middlename Lastname
Not all records have a middle name, so they may be 1 or 2 spaces in the column
I have tried this :
SELECT CONCAT ( SUBSTRING_INDEX(`name`, ' ', 1) , ' ' , SUBSTRING_INDEX(`name`, ' ', -1) ) AS nicename`
But this only gives the last name. The "-1" part is not working...
Thanks for all help.
To start with, that's a bad design, Now, since your middlename part may be empty, you may bear with it and just select the name saying select name from tbl1.
Else, consider re-designing your table to have separate columns for Lastname, Firstname and Middlename and then You don't need all of this. You can just get data from all 3 columns saying
select concat(Firstname, Middlename, Lastname ) as nicename
from tbl1;
Found a solution :
SELECT concat ( TRIM( SUBSTR(`name`, LOCATE(' ', `name`)) ), ' ', SUBSTRING_INDEX(SUBSTRING_INDEX(`name`, ' ', 1), ' ', -1) ) as nicename
Source: How to split the name string in mysql?
Actually in my case I need to select street number from a address string, which means if the string is '1234 dummy789 road', I only want to get '1234', not '1234789' Another example is 'Plot 111 dummy 1220' then i want only '111'. and if the string is '111/2 dummy' then i want to get '111/2'
I tried following:
SELECT CASE WHEN substr(address , 1, 1) between '0' and '9'
THEN substr(address , 1, 1)
ELSE 'False'
END as add
from test
<?php
$ab = "1225584454 red 1555 blue";
$result = explode(" ", $ab, 2);
print_r($result);
?>
in this case this will gives you first string in your variable.
Assuming that you have civil number followed by space and street name I would suggest the following:
Put WHERE statement with REGEXP to get those, which start with digit-followed-by-space. And in returned field get only numeric portion with substring.
Something like this:
SELECT SUBSTRING(address, 0, LOCATE(' ', address)) FROM items WHERE `address` REGEXP '^[0-9]+ '>0;
Correction:
SELECT TRIM(LEFT(address, LOCATE(' ', address))) FROM items WHERE `address` REGEXP '^[0-9]+ '>0;
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
I have and ORDERS table from a customer shopping cart. It's the typical customer name, address, etc..list of fields. The twist is that the cart will populate the shipping information into the appropriate fields (shipName, shipAddress, ShipState, etc) when the customer enters shipping information that is different then the billing information. However, when the customer ships to themselves, the cart does not move the shipping information to the proper fields for shipping (i.e., shipName, shipAddress, shipState). It keeps this information in the ordName, ordAddress, ordCity, etc fields and then keeps the shipping related fields empty.
Therefore, these shipping fields are then empty for orders that customers ship to themselves. I used IF commands to move the ordName, ordAddr, etc to alias names when no shipping information is provided so that the shipping information for all order types (whether the customer ships to themselves or to another address) is handled. That part is working fine in my query below.
One issue remains. My shipping program can't use long State name (e.g, Michigan, New York, etc). It needs the state to be the two character abbreviation (e.g, MI, NY). I have a look up table called *STATES that has a mapping between long state name and the two character abbreviation. I am trying to use the ShipState alias to look up the correct two character name for a given state. I tried to do this as a JOIN but keep getting errors. I removed the join I was using and am only showing the code that works correct right now but doesn't do the mapping for state abbreviation. Can someone please help?
SELECT
orders.ordDate AS `Date`,
orders.ordID AS Order_ID,
orders.ordEmail AS Email,
IF(ordShipName = ' ', ordName, ordShipName) AS Name,
IF(ordShipAddress = ' ', ordAddress, ordShipAddress) AS Address_1,
IF(ordShipAddress2 = ' ', ordAddress2, ordShipAddress2) AS Address_2,
IF(ordShipCity = ' ', ordCity, ordShipCity) AS City,
IF(ordShipState = ' ', ordState, ordShipState) AS ShipState,
IF(ordShipZip = ' ', ordZip, ordShipZip) AS Postal,
IF(ordShipCountry = ' ', ordCountry, ordShipCountry) AS Country,
IF(ordShipPhone = ' ', ordPhone, ordShipPhone) AS Phone,
FROM
orders
WHERE
orders.ordID > 21700
HAVING
Country = 'United States of America'
You can't use the column alias ShipState for the join to your lookup table. Instead, repeat your IF construct again:
SELECT
orders.ordDate AS `Date`,
orders.ordID AS Order_ID,
orders.ordEmail AS Email,
IF(ordShipName = ' ', ordName, ordShipName) AS Name,
IF(ordShipAddress = ' ', ordAddress, ordShipAddress) AS Address_1,
IF(ordShipAddress2 = ' ', ordAddress2, ordShipAddress2) AS Address_2,
IF(ordShipCity = ' ', ordCity, ordShipCity) AS City,
IF(ordShipState = ' ', ordState, ordShipState) AS ShipState,
IF(ordShipZip = ' ', ordZip, ordShipZip) AS Postal,
IF(ordShipCountry = ' ', ordCountry, ordShipCountry) AS Country,
IF(ordShipPhone = ' ', ordPhone, ordShipPhone) AS Phone,
STATE.StateAbbreviation
FROM
orders
INNER JOIN STATES
ON IF(orders.ordShipState = ' ', orders.ordState, orders.ordShipState) = STATES.State
WHERE
orders.ordID > 21700
HAVING
Country = 'United States of America'
You should put the code in where you try to join the two tables. You might just have a syntax error that someone could help you with. If you have a table called STATES with columns state and state_abrev, try this:
select ..., .., ..., STATES.state_abrev, ..., ..., from orders, STATES where STATES.state = orders.ordShipState AND ... ... HAVING ...
Since the origin of the data is a small set of transaction it will be very fast, I would have it do a left join to two instances of the states table respectively on their field and have your SELECT based on whichever was not empty... such as
select
...(other fields),
IF(orders.ordShipState = ' ', s1.StateName, s2.StateName ) as StateName
from
Orders
left outer join states s1
on orders.ordstate = s1.state
left outer join states s2
on orders.ordShipState = s2.state
where
orders.ordID > 21700
(etc with rest of query)...
This way, the join will always be having a join based on BOTH POSSIBLE states... So, whichever one exists, based on your preference, get THAT state first, otherwise get the other.