Within a table like this:
ID| ph_number
-----------
1 | 51231234
2 | 5123 1234
3 | 51231234; 61231234
4 | 5123 1234; 61231234
5 | 5123 1934; 6123 1234
6 | 5123 1234; 6123 1234
7 | aargh; 5123 1234; 6123 1234
, user needs to find a phone number (ex 51231234) not knowing where the spaces are, or if there are many numbers per field. I can find the numbers without spaces with query like this:
SELECT ID, ph_number FROM test WHERE REPLACE(ph_number, ' ', '') LIKE REPLACE('51231234', ' ', '')
that returns IDs 1 and 2, or
SELECT ID, ph_number FROM test WHERE ph_number LIKE '%51231234%'
that returns IDs 1 and 3. But Needed are IDs 1,2,3,4, 6 and 7. I'm not able to combine the two queries. Have tried:
SELECT ID, ph_number FROM test WHERE REPLACE(ph_number, ' ', '') LIKE ('%' + REPLACE('51231234', ' ', '') + '%') // returns 1 & 2
SELECT ID, ph_number FROM test WHERE REPLACE(ph_number, ' ', '') LIKE '%' + REPLACE('51231234', ' ', '') + '%' // returns ERROR
How could I achieve this? I wouldn't want to tell users that they can't have multiple numbers on the field.
In MySQL "+" is exclusively an arithmetic operator. Use the CONCAT() function to concatenate strings:
....WHERE REPLACE(ph_number, ' ', '') LIKE CONCAT('%', REPLACE('51231234', ' ', ''), '%')
Related
Im trying to write a query that will match partial matches to stored name values.
My database looks as follows
Blockquote
FirstName | Middle Name | Surname
----------------------------------
Joe | James | Bloggs
J | J | Bloggs
Joe | | Bloggs
Jane | | Bloggs
Now if a user enters their name as
J Bloggs
my query should return all 4 rows, as they are all potential matches.
Similarly if a user enters the name
J J Bloggs
all rows should be returned.
If a user enters their name as
Joe Bloggs
only the first three should be returned.
I have tried the following
SELECT *
FROM PERSON
WHERE CONCAT(' ',FirstName,' ',MiddleName,' ', Surname) LIKE '% Joe%'
AND CONCAT(' ',FirstName,' ',MiddleName,' ', Surname, ' ') LIKE '% Bloggs%';
But this doesn't return 'J J Bloggs'.
Any ideas?
If I understand your logic correctly, any of the three input name components is considered to be a match if it either is a substring of a value in the table, or vice-versa. That is, J matches Joe, but also Joe matches to J. Using this logic, we can write the following query:
SELECT *
FROM yourTable
WHERE
(INSTR(FirstName, 'J') > 0 OR INSTR('J', FirstName) > 0) AND
(INSTR(MiddleName, 'J') > 0 OR INSTR('J', MiddleName) > 0 OR MiddleName IS NULL) AND
(INSTR(Surname, 'Bloggs') > 0 OR INSTR('Bloggs', Surname) > 0);
Demo
Note that the middle name has some additional logic. If the middle name be missing in a record (i.e. it is NULL), then we wave the requirement for the middle names to match.
I think you might need OR instead of AND...
SELECT *
FROM PERSON
WHERE CONCAT(' ',FirstName,' ',MiddleName,' ', Surname) LIKE '% Joe%'
OR CONCAT(' ',FirstName,' ',MiddleName,' ', Surname, ' ') LIKE '% Bloggs%';
How to make an SQL query for a table based on the following conditions:
Result is a single column that concatenates all fields delimited by a dash into a single string (ex: FieldA-FieldB-FieldC-FieldD-FieldE)
If a given field is NULL or if the field's value is a string such as "EMPTY" or "NA", do not concatenate that field's value into the result string
Example Table Person (FirstName, LastName, Street, City, State):
Bob | Dylan | 555 Street | Mountain View | California
Ally | M | NULL | Seattle | Washington
Jan | Van | EMPTY | EMPTY | Oregon
Nancy | Finn | EMPTY | EMPTY | NA
Don | William | NULL | EMPTY | Illinois
Result:
Bob-Dylan-555 Street-Mountain View-California
Ally-M-Seattle-Washington
Jan-Van-Oregon
Nancy-Finn
Don-William-Illinois
I know this can be done programatically, but wanted to know if this can be done in SQL and if it would be more efficient to do so in the query itself.
Fully-baked solution for SQL Server 2017 and above:
SELECT *
FROM Person p
OUTER APPLY (
SELECT STRING_AGG(NULLIF(NULLIF(val, 'EMPTY'), 'NA'), '-')
WITHIN GROUP (ORDER BY n) AS val
FROM (VALUES (1, p.FirstName), (2, p.LastName),(3, p.Street),
(4,p.City), (5, p.State)) z(n, val)
)sub;
DBFiddle Demo
MySQL version using CONCAT_WS:
CONCAT_WS() stands for Concatenate With Separator and is a special form of CONCAT(). The first argument is the separator for the rest of the arguments. The separator is added between the strings to be concatenated. The separator can be a string, as can the rest of the arguments. If the separator is NULL, the result is NULL.
CONCAT_WS() does not skip empty strings. However, it does skip any NULL values after the separator argument.
SELECT CONCAT_WS('-',
NULLIF(NULLIF(FirstName, 'EMPTY'), 'NA'),
NULLIF(NULLIF(LastName, 'EMPTY'), 'NA'),
NULLIF(NULLIF(Street, 'EMPTY'), 'NA'),
NULLIF(NULLIF(City, 'EMPTY'), 'NA'),
NULLIF(NULLIF(State, 'EMPTY'), 'NA')) AS r
FROM Person p;
DBFiddle Demo2
first, use CONCAT to concatenate the fields.
then use REPLACE to replace NULL values
SELECT REPLACE( CONCAT( field1, "-", field2 , "-", field3) , "NULL", "EMPTY" )
FROM `table`
Try This
SELECT ISNULL(FirstName,'') + '-' +
ISNULL (LastName,'') + '-' +
ISNULL (City,'') + '-' +
ISNULL (State,'')
FROM Person
OR LIKE THIS
SELECT CASE WHEN ISNULL(FirstName,'') = '' THEN '' ELSE FirstName + '-' +
CASE WHEN ISNULL(LastName,'') = '' THEN '' ELSE LastName + '-' +
CASE WHEN ISNULL(City,'') = '' THEN '' ELSE City + '-' +
CASE WHEN ISNULL(State,'') = '' THEN '' ELSE State + '-' END AS
ColumnName
FROM Person
Your select should be something like this:
select isnull(FieldA,'')+ '-' + isnull (FieldB,'') + '-' + isnull (FieldC,'') ....
and so on ..
This will work on MS SQL server if you don't want '-' if previous field is null than you should use case statement.
If you want to replace also 'Empty' or 'NULL' strings than you should use:
select replace(replace( isnull(FieldA+'-','') , 'Empty' , ''),'Null', '')
I have modified isnull() by Nitin_g3 observation.
I have a table called "tblVersion" that looks something like...
| key | value |
|-------------------------|
| buildVersion | 5 |
| minorVersion | 4 |
| majorVersion | 2 |
I want to build a query that will return the string "2.4.5", i.e. majorVersion.minorVersion.buildVersion.
So far I have
SELECT GROUP_CONCAT(tblVersion.value SEPARATOR '.' ) AS softwareVersion
FROM tblVersion
WHERE tblVersion.key = 'majorVersion'
OR tblVersion.key = 'minorVersion' OR tblVersion.key = 'buildVersion'
This returns "5.2.4" and I can't seem to get the string in the correct order.
Is it possible to be specific about the order the values are displayed?
Use order by FIELD
SELECT GROUP_CONCAT(value order by FIELD(tblVersion.key , 'majorVersion', 'minorVersion' , 'buildVersion') SEPARATOR '.' ) AS softwareVersion
FROM tblVersion
WHERE tblVersion.key = 'majorVersion'
OR tblVersion.key = 'minorVersion' OR tblVersion.key = 'buildVersion';
http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_field
demo: http://sqlfiddle.com/#!2/8ef367/4
You should be able to use a CASE expression in the GROUP_CONCAT function:
select
group_concat(`value`
order by
case `key`
when 'majorVersion' then 0
when 'minorVersion' then 1
else 'buildVersion' end SEPARATOR '.') SoftwareVersion
from tblVersion
See SQL Fiddle with Demo
If DhruvPathak is on the right lines in regards to what you're actually after, then that can be achieved this way...
SELECT GROUP_CONCAT(x.value ORDER BY FIELD(x.key,'minorversion','majorversion','buildversion') DESC SEPARATOR '.') softwareVersion
FROM tblversion x
WHERE x.key IN('minorVersion','majorVersion','buildVersion');
I have a field name with the following rows:
`name`
------
John Smith
George Washington
Ash Ketchum
Bill O'Reilly
I would like to reformat the rows on output:
`name`
------
SMITH, JOHN
WASHINGTON, GEORGE
KETCHUM, ASH
O'REILLY BILL
I know I can use upper( x.name ) for casing, but how can I reformat the names?
Assuming your rdbms is mySql, answer will need to be tailored to differenct dialects of sql.
SELECT concat( substring(name, locate(name, ' ')), ', ', substring(name, 0, locate(name, ' ') - 1)) FROM NAMES;
The real problem here however is data integrity. You need to have seperate columns for each peice of the name so that formating in the database is ensured to be consitent. Ideally you would want to be doing this --
Select concat(last_name, ', ', first_name) FROM NAMES;
Allowing
'name'
-------------------
John Smith
Smith, John
J Smith
Smith J
John q Smith
Jhon 'the smithmeister' Smith
All in the same column of a table is a bad thing for a number of reasons so this should be explictly prevented.
Try this:
SELECT SUBSTRING_INDEX( `name` , ' ', -1 ) + ', ' + SUBSTRING_INDEX( `name` , ' ', 1 )
FROM MyTable
#Ben, makes a good point about names with multiple spaces in them. I doubt this would give you the output you want in those cases, but it should get you started.
try this
SELECT Concat(SUBSTRING_INDEX( `name` , ' ', -1 ) , ', ' , SUBSTRING_INDEX( `name` , ' ', 1 )) as name
FROM your_Table
I need to count the repeats of search keyword in searched fields.
For example, if i have table wp_posts like this
ID post _content post_title
-----------------------------------------------
1 page page page page
2 page test page
3 page foo test
I want result like if any one search for page
ID total count
1 4
1 2
2 1
try this
SELECT id ,
FLOOR(( (length(REPLACE(post_content, '', ''))
- length(REPLACE(REPLACE(post_content, ' ', ''),
'page', ''))) ) / length('page'))
+ FLOOR(( (length(REPLACE(post_title, ' ', ''))
- length(REPLACE(REPLACE(post_title, '
', ''), 'page', ''))) ) / length('page')) "count of 'page'"
FROM page_search ;