SQL LIKE operator not working for comma-separated lists - sql

Here is my data:
Column:
8
7,8
8,9,18
6,8,9
10,18
27,28
I only want rows that have and 8 in it. When I do:
Select *
from table
where column like '%8%'
I get all of the above since they contain an 8. When I do:
Select *
from table
where column like '%8%'
and column not like '%_8%'
I get:
8
8,9,18
I don't get 6,8,9, but I need to since it has 8 in it.
Can anyone help get the right results?

I would suggest the following :
SELECT *
FROM TABLE
WHERE column LIKE '%,8,%' OR column LIKE '%,8' OR column LIKE '8,%' OR Column='8';
But I must say storing data like this is highly inefficient, indexing won't help here for example, and you should consider altering the way you store your data, unless you have a really good reason to keep it this way.
Edit:
I highly recommend taking a look at #Bill Karwin's Link in the question's comment:
Is storing a delimited list in a database column really that bad?

You could use:
WHERE ','+col+',' LIKE '%,8,%'
And the obligatory admonishment: avoid storing lists, bad bad, etc.

How about:
where
col like '8,%'
or col like '%,8,%'
or col like '%,8'
or col = '8'
But ideally, as bluefeet suggests, normalizing this data instead of storing as delimited text will save you all kinds of headaches.

Related

Group by in SQL using first two digits

I have a column storing codes like 71xxxx, 78xxxx, 59xxxx, and so on. I need to run a query to find out all the records that have codes starting with 71.
I mean, all the rows where the the first two digits of the code column are 71. If anyone can share the SQL query for this, I would be really helpful.
Thanks.
You would use like in a where clause for the filtering:
where code like '71%'
This is pretty basic SQL. If you are not familiar with it, you should study the language a bit more.
Try this
select substr(col, 1,2),count(*) from ITEM group by substr(col, 1,2)

How to specify a group of years in a table in SQL

Basic SQL question about specifying a group of years in a table. Working on a database and it is wanting me to list the author, title, publication date and retail price. I have that part down but its also ask to output all titles that start with "D" and were published in the 1970s.
I have the first part down: (this is how we are taught btw)
SELECT `fAuthorID`,`fTitle`,`fPubYear`,`fRetailPrice`
FROM `tBooks`
WHERE
But I cant seem to be able to get it to output the authors with a "D" and years 1970-1979 to display.
Assuming fpubyear is a number (integer) column, the correct way of querying for a continuous range of years is to use the BETWEEN operator.
SELECT fauthorID, fTitle, fPubYear, fReatailPrice
FROM tbooks
WHERE fTitle Like 'D%'
AND fPubYear BETWEEN 1970 and 1979;
The between operator includes both ends. It has the added benefit that an index on fpubyear can be used to quickly find the matching rows - which is not the case if the number first needs to be converted to a string to be able to apply the LIKE operator on it.
LIKE is for character values ("strings"), it should not be used with other types - especially not when relying on the evil implicit data type conversion. Other database would simply reject applying like on a number column.
SELECT fauthorID, fTitle, fPubYear, fReatailPrice
FROM tbooks
WHERE fTitle Like 'D%' AND fPubYear Like '197_'
Hi Dewie You an use this query,
SELECT fAuthorID,fTitle,fPubYear,fRetailPrice
FROM tBooks
WHERE fTitle like 'D%' and fPubYear like '%197%';
Hope this will give you result. Any issues just let me know

need to add to this LIKE clause on IBM i SQL

I have a VIEW with these WHERE Conditions. I would like to add another type on the 3 rd line here
I want also those rows with like as "FR" is there a way to sort of have such a group like that under the LIKE clause?
ASTDTA.ICPRTMIA.IARCC9='ACS' AND
ASTDTA.OEINDLID.IDCOM#='001' AND
ASTDTA.OEINDLID.IDPRT# LIKE 'ACS%' AND
ASTDTA.ADRESSAD.ADSFX# =
SUBSTR(ASTDTA.OEINDLID.IDGRC#,9,3
Use an OR condition:
ASTDTA.ICPRTMIA.IARCC9='ACS' AND
ASTDTA.OEINDLID.IDCOM#='001' AND
(ASTDTA.OEINDLID.IDPRT# LIKE 'ACS%' OR ASTDTA.OEINDLID.IDPRT# LIKE 'FR%') AND
ASTDTA.ADRESSAD.ADSFX# =
SUBSTR(ASTDTA.OEINDLID.IDGRC#,9,3
If you've only got a small handful of patterns, then use JamesA's answer. But if you find you have a bunch, then put your patterns in a table, or a temp table, or possibly just a common table expression with a values statement in it. Let's call it RULES. Now you can join to it, and say
ASTDTA.OEINLID.IDPRT# LIKE RULES.PATTERN

How to retrieve a part of a value in a column

Correction - I only need to Pick the WORK value every result set in the column will contain comma seperated values like below..
"SICK 0.08, WORK 0.08" or "SICK 0.08,WORK 0.08"
I only need to pick WORK 0.08 from this.
I am quite new to SQL
I am using the following script to get some results;
select Work.Work_summary, Work.emp_id
from Work
all work fine. but the first column has values like the following :
WORK 08.57, SICK 08.56 (Some columns)
SICK 07.80, WORK 06.80 , OT 02.00 (Some columns)
How can i only retrieve the column with only the WORK% value, if there is no WORK value the results shall be empty.
select Work_summary, emp_id
from Work
where Work_summary like '%WORK%'
This will return the rows in the Work table where Work_summary column contains the word WORK. See the documentation for more details.
Contains is faster than like.
SELECT Work_summary, emp_id FROM Work WHERE CONTAINS(Work_summary, 'WORK');
then use: this will give only the result where work summary contains work content.
select Work.Work_summary, Work.emp_id
from Work where contains(work.Work_summary ,'work');
select replace(Work_summary,",","") as work_summary
from Work
where upper(Work_summary) like '%WORK%'

How to handle string ordering in order by clause?

Suppose I want to order the records order by a field (string data type) called STORY_LENGTH. This field is a multi-valued field and I represent the multiple values using commas. For example, for record1, its value is "1" and record2 its value is "1,3" and for record3 its value is "1,2". Now when, I want to order the records according to STORY_LENGTH then records are ordered like this record1 > record3 > record2. Its clear that STORY_LENGTH data type is string and order by ASC is ordering that value considering it as string. But, here comes the problem. For example, when record4="10" and record5="2" and I try to order it looks like record4 > record5 which obviously I don't want. Because 2 > 10 and I am using a string formatted just because of multiple values of the field.
So, anybody, can you help me out of this? I need some good idea to fix.
thanks
Multi-values fields as you describe mean your data model is broken and should be normalized.
Once this is done, querying becomes much more simple.
From what I've understood you want to sort items by second or first number in comma separated values stored in a VARCHAR field. Implementation would depend on database used, for example in MySQL it would look like:
SELECT * FROM stories
ORDER BY CAST(COALESCE(SUBSTRING_INDEX(story_length, ',', -1), '0') AS INTEGER)
Yet it is not generally not good to use such sorting for performance reasons as sorting would require scanning of whole table instead of using index on field.
Edit: After edits it looks like you want to sort on first value and ignore value(s) after comma. As according to some comment above changes in database design are not an option just use following code for sorting:
SELECT * FROM stories
ORDER BY CAST(COALESCE(NULLIF(SUBSTRING_INDEX(story_length, ',', 1), ''), '0') AS INTEGER)