I have an SQL table called Codes with a primary column code of type String.
I also have another table called Items with a column codestring also of type String. This entry always contains a string with some of the codes of the above table separated by spaces.
Now I want to get all codes and their number of Items containing the respective code. Can I do that?
Codes:
code|...
----|---
"A0A"|
"A0B"|
...|
Items:
...|codestring
----|---------
|"A0A C2B F1K"
|"A0C D2S H3K"
|...
Output:
Codes:
code|...|noOfItems
----|---|---------
"A0A"|...|5
"A0B"|...|10
...|...|...
Assuming all the codes are distinct (or at least no code is a substring of another code), you can use the LIKE operator:
(untested)
SELECT codes.code, count(*)
FROM codes LEFT JOIN items ON items.codestring LIKE '%' + codes.code + '%'
GROUP BY codes.code;
You have a horrible data format and should fix it. The mapping to codes should have a separate row for each code.
If the codes are all three characters, then L Scott Johnson's answer is close enough. Otherwise, you should take the delimiter into consideration:
SELECT c.code, count(i.codestring)
FROM codes c LEFT JOIN
items i
ON ' ' || i.codestring || ' ' LIKE '% ' || c.code || ' %'
GROUP BY c.code;
Note other fixes to the code:
The concatenation operator is the standard ||.
The count() will return 0 if there are no matches.
Related
The following code is working fine when the column 'generated_key ' return one value
WHERE code IN ( SELECT generated_key FROM List_agg )
CODE
generated_key
EU00100ST10000016
EU00100ST10000016
But when the column generated_key containt more than a values, it return 0 rows
CODE
generated_key
EU00100ST10000016
EU00100ST10000016, EU00100ST10000017
If you need to compare to a list, use delimited comparisons
WHERE EXISTS (SELECT 1
FROM list_agg
WHERE ',' || generated_key || ',' LIKE '%,' || code ',%'
)
The "list_agg" name suggests that you are aggregating values from another query. If so, you might be able to use use in with no aggregation. But your question doesn't have enough details to know if that is really the case.
My SQL Server database table has a column text which is a long string of text.
The search list is a string of words separated by comma. I want to grab those rows where the text column contains any one of words in the string.
DECLARE #words_to_search nvarchar(50)
SET #words_to_search = 'apple, pear, orange'
SELECT *
FROM myTbl
WHERE text ??? --how to specify text contains #words_to_search
Thanks a lot in advance.
If you're running SQL Server 2016 or later, you can use STRING_SPLIT to convert the words to search into a single column table, and then JOIN that to your table using LIKE:
DECLARE #words_to_search nvarchar(50)
SET #words_to_search = 'apple,pear,orange'
SELECT *
FROM myTbl
JOIN STRING_SPLIT(#words_to_search, ',') ON text LIKE '%' + value + '%';
Demo on SQLFiddle
Note that as the query is written it will (for example) match apple within Snapple. You can work around that by making the JOIN condition a bit more complex:
SELECT *
FROM myTbl t
JOIN STRING_SPLIT(#words_to_search, ',') v
ON t.text LIKE '%[^A-Za-z]' + value + '[^A-Za-z]%'
OR t.text LIKE value + '[^A-Za-z]%'
OR t.text LIKE '%[^A-Za-z]' + value;
Demo on SQLFiddle
First, I would use exists, unless you want to return the matching word.
Second, you can do this with a single like comparison If words are separated by spaces:
select t.*
from t
where exists (select 1
from string_split(#words_to_search, ',') s
where ' ' + t.text + ' ' like '% ' + value + ' %'
);
For more generic separators, you can use:
select t.*
from t
where exists (select 1
from string_split(#words_to_search, ',') s
where ' ' + t.text + ' ' like '%[^A-Za-z]' + value + '[^A-Za-z]%'
);
Or whatever describes your separators.
Note that your list of words is separated by a comma-space, not just a comma. However, based on your description (not the sample data), I have only used a ',' for the separator.
So like my question says, I'm trying to get three strings into a single one, separated by a " ' " between them and then storing that resulting string into a different column (more than one case, so maybe I also need a loop?)
Here's what I have:
select 'insertGeneric(''' ||b.DESCRIPTION, b.name, get_json_v(a.value, 'svgName') SYMBOL from cat_entity b
left join CAT_ENTITY_ATTRIBUTE a on b.id = a.id_cat_entity and a.NAME = 'styleOsp'
where b.name like 'LOC.PHYSICAL.IP.%';
insertGeneric('Cabinet', 'LOC.PHYSICAL.IP.236','CABINETA');
Trying to get those together, the third one is also removes the ".svg" from the string and basicly then storing them where I find the subtring 'LOC.PHYSICAL.IP.%'.
get_json_v is a function from my project, gives me string with name of the file.
I tried using a CONCAT() function but couldn't get it to work.
A friend suggested I did the concatenation with excell and then import , but I have no idea on how I would do that, so I prefer
with SQL.
Any help is appreciated.
Not sure I follow all of your question, but you can concatenate all the values and single quotes using the concaenation operator you are aldready using:
select 'insertGeneric(''' ||b.DESCRIPTION ||''','''|| b.name ||''','''||
get_json_v(a.value, 'svgName') || ''')' SYMBOL
from cat_entity b
left join CAT_ENTITY_ATTRIBUTE a on b.id = a.id_cat_entity and a.NAME = 'styleOsp'
where b.name like 'LOC.PHYSICAL.IP.%';
So where you were separating the columns with a comma, you instead seperate the values with ||''','''||.
You might find it slightly clearer broken down a bit:
select 'insertGeneric('
|| '''' || b.DESCRIPTION || ''''
|| ','
|| '''' || b.name || ''''
|| ','
|| '''' || get_json_v(a.value, 'svgName') || ''''
|| ')'
as SYMBOL
from cat_entity b
left join CAT_ENTITY_ATTRIBUTE a
on b.id = a.id_cat_entity and a.NAME = 'styleOsp'
where b.name like 'LOC.PHYSICAL.IP.%';
That will gove you a string holding a statement as you've shown, but it isn't clear what you will do with it - perhaps you are building up ananonymous block of statements to run dynamically.
Was working on SQL-EX.ru exercises.
There is one question for DML that I could not do, but I cannot proceed to the next one, until this one is done.
the question itself: All the trailing spaces in the name column of the Battles table remove and add them at the beginning of the name.
My code:
Update Battles
set name=concat(' ',(LTRIM(RTRIM(name))))
The system does not let it go through, I understand that I am using ' ' for the concat, whereas I need to use the stuff that got trimmed. And I have no idea how...
Any help would be very much appreciated
Try Something Like:-
set name = lpad(trim(name), length(trim(name))+4, ' ')
Here use TRIM to remove space from both side. use LPAD to add something on left side with n (4) chars
I'm not familiar with SQL-EX.ru, but if it's Oracle compatible and you can use regular expressions (or you are at that point in the training) here's a way. Maybe it'll give you an idea at least. The first part is just setup and uses a WITH clause to create a table (like a temp table in memory, actually called a Common Table Expression or CTE) called battles containing a name column with 2 rows. Each name column datum has a different number of spaces at the end. Next select from that column using a regular expression that uses 2 "remembered" groups surrounded by parentheses, the first containing the string up to until but not including the first space, the second containing 0 or more space characters anchored to the end of the line. Replace that with the 2nd group (the spaces) first, followed by the first group (the first part of the string). This is surrounded by square brackets just to prove in the output the same spaces were moved to the front of the string.
SQL> with battles(name) as (
select 'test2 ' from dual union
select 'test1 ' from dual
)
select '[' || regexp_replace(name, '(.*?)([ ]*)$', '\2\1') || ']' fixed
from battles;
FIXED
----------------------------------------------------------------------------
[ test1]
[ test2]
SQL>
I hope this solution can be applied to your problem or at least give you some ideas.
Try this:
set name = case when len(name) > len(rtrim(name))
then replicate(' ', len(name) - len(rtrim(name))) + rtrim(name)
else name
end
update battles
set name = case when (len(name+'a')-1) > len(rtrim(name))
then
replicate(' ',
(len(name+'a')-1) - len(rtrim(name))) + rtrim(name)
else name
end
Len() doesn't count trailing spaces. So using (len(name+'a')-1).
Simplest answer:
UPDATE Battles
SET name = SPACE(DATALENGTH(name)-DATALENGTH(RTRIM(name))) + RTRIM(name)
But only works because name is VARCHAR.
More generic is to do:
UPDATE Battles
SET name = SPACE(len(name+'x')-1-len(RTRIM(name))) + RTRIM(name)
simple example below ... enjoy :)
update battles set name =
Space( DATALENGTH(name) - DATALENGTH(rtrim(name))) + rtrim(name)
where date in ( select date from battles)
I need to get a list of names as per the following format
"Mr."+first name initial+last name+"."
There is only one table for this
salesperson (f_name, l_name)
What i have been trying is;
SELECT 'Mr.' ||' ' || SUBSTRING(f_name,1,1) || ' ' || l_name ||’.’||
FROM salesperson;
It works without the substring or left, but not if I include them.
Use concat instead of || operator to concatenate strings in MySQL. As you have it, it would be interpreted as logical OR condition, hence you get the error.
SELECT CONCAT('Mr.',' ',SUBSTRING(f_name,1,1),' ',l_name,'.')
FROM salesperson;
Oracle solution
SELECT 'Mr.'||' '||SUBSTR(f_name,1,1)||' '||l_name||'.'
FROM salesperson;
It is better practice anyways to grab the name data in full and then format it in the view part of your application with languages that are more suited to string manipulation. This also makes your code more reusable.
That being said use this
SELECT CONCAT("Mr. ",SUBSTRING( f_name, 1, 1 ) ," ",l_name,".") FROM salesperson