SQL count string matches in each row - sql

Please take a look at this simple SQL server database :
What I want is, I want to create a summary with only 3 column, here is the code:
select ProductID, Name,
*code* as CountString
from product
where Name in ('this', 'is', 'count', 'example')
I want the result to have 3 column, and the column "CountString" is the total number of string that matches ('this','is', 'count', 'example'). Here is the result I want :
So for example, I want the Countstring for ProductID 1 is 4, because it contains all of 4 words.
If you can solve this, it would be amazing!

If I understand correctly:
select ProductID, Name,
( (case when Name like '%this%' then 1 else 0 end) +
(case when Name like '%is%' then 1 else 0 end) +
(case when Name like '%count%' then 1 else 0 end) +
(case when Name like '%example%' then 1 else 0 end)
) as CountString
from product;
Note: Any Name that has "this" also has "is".
If "words" are separated by spaces (and only spaces), you can do:
select ProductID, Name,
( (case when concat(' ', Name, ' ') like '% this %' then 1 else 0 end) +
(case when concat(' ', Name, ' ') like '% is %' then 1 else 0 end) +
(case when concat(' ', Name, ' ') like '% count %' then 1 else 0 end) +
(case when concat(' ', Name, ' ') like '% example %' then 1 else 0 end)
) as CountString
from product;

The following query should suffice your need ---
SELECT PRODUCTID,
NAME,
REGEXP_COUNT(NAME, 'this|is|count|example', 1, 'c') CountString
FROM product;
This query will result in "Case Sensitive" checking, means only "example" will be counted not "Example". If you want "Case Insensitive" checking just put 'i' instead of 'c'.

Related

How to count unique integers in a string using hive?

Trying to count the unique bytes in a string?
DATA (Phone numbers for example with only numeric bytes):
1234567890
1111111112
Results:
10
2
I have tried the below and it didn't work because the sum() won't accept the UDF 'if' with in it, I think.
select phone
, sum(
cast(if(length(regexp_replace(phone,'0',''))<10,'1','0') as int) +
cast(if(length(regexp_replace(phone,'1',''))<10,'1','0') as int) +
cast(if(length(regexp_replace(phone,'2',''))<10,'1','0') as int) +
cast(if(length(regexp_replace(phone,'3',''))<10,'1','0') as int) +
cast(if(length(regexp_replace(phone,'4',''))<10,'1','0') as int) +
cast(if(length(regexp_replace(phone,'5',''))<10,'1','0') as int) +
cast(if(length(regexp_replace(phone,'6',''))<10,'1','0') as int) +
cast(if(length(regexp_replace(phone,'7',''))<10,'1','0') as int) +
cast(if(length(regexp_replace(phone,'8',''))<10,'1','0') as int) +
cast(if(length(regexp_replace(phone,'9',''))<10,'1','0') as int)
) as unique_bytes
from table;
I am not apposed to regular expressions as a solution either.
Use + . . . but like this:
select phone,
((case when phone like '%0%' then 1 else 0 end) +
(case when phone like '%1%' then 1 else 0 end) +
(case when phone like '%2%' then 1 else 0 end) +
(case when phone like '%3%' then 1 else 0 end) +
(case when phone like '%4%' then 1 else 0 end) +
(case when phone like '%5%' then 1 else 0 end) +
(case when phone like '%6%' then 1 else 0 end) +
(case when phone like '%7%' then 1 else 0 end) +
(case when phone like '%8%' then 1 else 0 end) +
(case when phone like '%9%' then 1 else 0 end) +
) as ints
from table;
Your code has several issues:
sum() is an aggregation function and is not needed.
The if() is returning strings, but you are adding the values together.
I'm not sure why you are using regexp_replace() rather than just replace().
with tab1 as (
select stack(3,
'1','1234567890',
'2','1111111112',
'3','2222222223') as (col0, col1))
select tab1.col0, count(distinct tf.col) from tab1 lateral view explode(split(tab1.col1,'')) tf as col
where tf.col regexp '\\d'
group by tab1.col0

Update using case in two fields

I need to use the query below in an update in order to update the first and last name. What's the best option to do that?
SELECT
person.fullName,
(CASE WHEN 0 = CHARINDEX(' ', person.fullName)
then person.fullName
ELSE SUBSTRING(person.fullName, 1, CHARINDEX(' ', person.fullName)) end) as first_name,
(CASE WHEN 0 = CHARINDEX(' ', person.fullName)
THEN ''
ELSE SUBSTRING(person.fullName,CHARINDEX(' ', person.fullName), LEN(person.fullName) )end) last_name
FROM person
Thank you.
Please Try this code, i did not modify your condition , but showing you the logic to use your code to update first and last name. I assume the table has FirstName and LastName columns
UPDATE Person
SET
Person.FirstName =
(CASE WHEN 0 = CHARINDEX(' ', person.fullName)
then person.fullName
ELSE SUBSTRING(person.fullName, 1, CHARINDEX(' ', person.fullName)) end) ,
Person.LastName =
(CASE WHEN 0 = CHARINDEX(' ', person.fullName)
THEN ''
ELSE SUBSTRING(person.fullName,CHARINDEX(' ', person.fullName), LEN(person.fullName) )end)
FROM person

convert certain column names with comma separated string from sql table with conditions

For example , I have this table with different column names and the Boolean value below it,
case1 case2 case3 case4
1 0 1 0
What I want to retrieve,only column names with 1 value. So, my desired results from the query should only be case1,case3
Desired Output : case1,case3
there is only one row fetch from sql query
Is there any way?
If I understand correctly, you could use a big case statement:
select stuff(( (case when case1 = 1 then ',case1' else '' end) +
(case when case2 = 1 then ',case2' else '' end) +
(case when case3 = 1 then ',case3' else '' end) +
(case when case4 = 1 then ',case4' else '' end)
), 1, 1, '') as columns
In the case you have multiple rows.
Query
select stuff((
(case when count(*) = sum(cast(case1 as int)) then ',case1' else '' end) +
(case when count(*) = sum(cast(case2 as int)) then ',case2' else '' end) +
(case when count(*) = sum(cast(case3 as int)) then ',case3' else '' end) +
(case when count(*) = sum(cast(case4 as int)) then ',case4' else '' end)), 1, 1, '')
as no_zero_columns
from your_table_name;
SQL Fiddle Demo

MS sql combine columns in select

I am trying to combine multiple columns (varchar, but used to store boolean 'Y' or '') into a single column (list) with human readable text.
The Table layout is like this:
MEMBER_ID (int) | PROC (varchar) | 50K_12_MTHS (varchar) | 100K_12_MTHS (varchar)
1||||
2|Y|Y||
3|Y|Y|Y|
4|Y|||
For the output of the able sample I am trying to get:
1|
2|Proc, 50
3|Proc, 50, 100
4|Proc
I think the way to do this is with a Case (see below) but can't get it to work.
SELECT
MEMBER_ID,
Gorup =
Select(
CASE PROC
WHEN 'Y'
THEN 'Proc'
END + ', ' +
CASE 50K_12_MTHS
WHEN 'Y'
THEN '50K'
END-- + ', ' +
CASE 100K_12_MTHS
WHEN 'Y'
THEN '100K'
END + ', ' +)
from Members
Nearly...!
SELECT
MEMBER_ID,
CASE [PROC]
WHEN 'Y' THEN 'Proc, '
ELSE ''
END +
CASE [50K_12_MTHS]
WHEN 'Y' THEN '50K,'
ELSE ''
END +
CASE [100K_12_MTH]
WHEN 'Y' THEN '100K, '
ELSE ''
END as [group]
from Members
Try this
SELECT
MEMBER_ID,
(CASE [PROC] WHEN 'Y'
THEN 'Proc' ELSE ''
END +
CASE [50K_12_MTHS] WHEN 'Y'
THEN ', 50K' ELSE '' END
+ CASE [100K_12_MTHS] WHEN 'Y'
THEN ', 100K' ELSE ''
END) as [GROUP]
from Members

Create related records based on string in SQL Server

I need to create a query that takes rows from a table and inserts into a related table all the splitted strings.
Example:
In table Keywords I have the row:
Id Name
1 RENAULT CLIO MTV
And I need to create a query that takes the row and create 1 row for each word like this:
In the table KeywordSearches:
Id: (Identity Increment)
Name: RENAULT
Keyword_Id: 1
Id: (Identity Increment)
Name: CLIO
Keyword_Id: 1
Id: (Identity Increment)
Name: MTV
Keyword_Id: 1
I need to be able to create all the related Keyword Search based on every rows of the table Keywords.
Thanks.
One way to get the list of keywords is to use a recursive CTE:
with keywords as (
select 1 as id, 'RENAULT CLIO MTV' as keywords union all
select 2 as id, 'A B' as keywords
),
cte as (
select id,
(case when keywords like '% %'
then left(keywords, charindex(' ', keywords))
else keywords
end) as keyword,
(case when keywords like '% %'
then substring(keywords, charindex(' ', keywords)+1, 1000)
else ''
end) as rest
from keywords
union all
select id,
(case when rest like '% %'
then left(rest, charindex(' ', rest))
else rest
end) as keyword,
(case when rest like '% %'
then substring(rest, charindex(' ', rest)+1, 1000)
else ''
end) as rest
from cte
where len(rest) > 0
)
select id, keyword
from cte;
Using the same structure, you can replace the final select with an insert:
insert into KeywordSearches(name, keyword_id)
select keyword, id
from CTE;
This assumes that you have set up the id as an identity column.
Here is a SQLFiddle for the first query.
EDIT:
I think the final query would be something like:
with cte as (
select id,
(case when keywords like '% %'
then left(keywords, charindex(' ', keywords))
else keywords
end) as keyword,
(case when keywords like '% %'
then substring(keywords, charindex(' ', keywords)+1, 1000)
else ''
end) as rest
from keywords
union all
select id,
(case when rest like '% %'
then left(rest, charindex(' ', rest))
else rest
end) as keyword,
(case when rest like '% %'
then substring(rest, charindex(' ', rest)+1, 1000)
else ''
end) as rest
from cte
where len(rest) > 0
)
insert into KeywordSearches(name, keyword_id)
select keyword, id
from CTE;