Reputation: 10824
I have a table in SQL Server called tbl_spe
that contains some specifications of a computer like CPU, RAM,...
I want to select all rows with this condition: all rows that their RAM are less than 1GB
We can simply write this query:
Select * from tbl_spe where RAM <= 1
Or something like that, but the problem is about table's data :
ID RAM
159 2GB DDR2
160 256MB DDR
161 3GB DDR2
162 512MB DDR
How can I extract number's part of the RAM field? and tell to query select all row that their RAM are less than 1GB?
Upvotes: 5
Views: 336
Reputation: 5869
;WITH CTE AS
(
SELECT *,
CONVERT(varchar(100), LEFT(RAM, PATINDEX('%[a-z]%', RAM) - 1)) AS RAMValue,
RIGHT(CONVERT(varchar(100), LEFT(RAM, PATINDEX('%[ ]%', RAM) - 1)), 2) AS RAMFactor
FROM tbl
)
SELECT *
FROM CTE
WHERE RAMFactor = 'MB'
Here is an example in SQLFiddle
If you wanted to have less than 2GB then change the WHERE clause to this:
WHERE RAMFactor = 'MB'
OR (RAMFactor = 'GB' AND RAMValue < 2)
The first check will get all records that are measured in 'MB', therefore less than a 'GB'. The second check will get all records that are measured in 'GB' and have a value of less than 2, therefore 'GB' values less than 2GB.
Upvotes: 5
Reputation: 16310
I have taken value(size) extraction part of RAM field using @XN16 query and used CASE
condition in WHERE
clause to apply the condition according to the size given.
SELECT * FROM tbl_spe
WHERE 1 <=
CASE
WHEN CHARINDEX('MB',SUBSTRING(RAM, 1, CHARINDEX(' ', RAM) - 1)) > 0
THEN CAST(CONVERT(varchar(100), LEFT(RAM, PATINDEX('%[a-z]%', RAM) - 1)) AS FLOAT) * 0.001
WHEN CHARINDEX('GB',SUBSTRING(RAM, 1, CHARINDEX(' ', RAM) - 1)) > 0
THEN CAST(CONVERT(varchar(100), LEFT(RAM, PATINDEX('%[a-z]%', RAM) - 1)) AS FLOAT)
END
In above CASE
condition, you can add the case for KB and add the logic to get GB from given size of KB.....
Check out SQLFIDDLE
Upvotes: 4
Reputation: 28741
SELECT * FROM tbl_spe
WHERE CAST( SUBSTRING(RAM,0,PATINDEX('%[a-zA-Z]%',RAM)) AS INT ) <=1
PATINDEX('%[a-zA-Z]%',RAM)
finds the position of first alphabet and SUBSTRING function extracts number from string.
EDIT : Below query takes into consideration RAM in MB and GB . Otherwise above query incorrectly returns 256MB Ram greater than 1GB
SELECT * FROM tbl_spe
WHERE
( CAST( SUBSTRING(RAM,0,PATINDEX('%[a-zA-Z]%',RAM)) AS INT ) <=1 AND
RAM like '%GB%' )
OR
( CAST( SUBSTRING(RAM,0,PATINDEX('%[a-zA-Z]%',RAM)) AS INT ) <=1000 AND
RAM like '%MB%' )
Upvotes: 4
Reputation: 45
Well I have crossed the same problem so I created my own function for this (of course I got some help from my friends in the internet) this is the function:
CREATE FUNCTION ExtractInteger(@String VARCHAR(2000))
RETURNS VARCHAR(1000)
AS
BEGIN
DECLARE @Count INT
DECLARE @IntNumbers VARCHAR(1000)
SET @Count = 0
SET @IntNumbers = ''
WHILE @Count <= LEN(@String)
BEGIN
IF SUBSTRING(@String,@Count,1) >= '0'
AND SUBSTRING(@String,@Count,1) <= '9'
BEGIN
SET @IntNumbers = @IntNumbers + SUBSTRING(@String,@Count,1)
END
SET @Count = @Count + 1
END
RETURN @IntNumbers
END
GO
Upvotes: 1
Reputation: 4892
Two steps:
1) Run a custom function to just extract the numeric values from RAM
column.
CREATE Function [dbo].[RemoveNumericCharacters](@Temp VarChar(1000))
Returns VarChar(1000)
AS
Begin
Declare @NumRange as varchar(50) = '%[0-9]%'
While PatIndex(@NumRange, @Temp) > 0
Set @Temp = Stuff(@Temp, PatIndex(@NumRange, @Temp), 1, '')
Return @Temp
End
2) And second step, simply use the function
WITH CTE
AS
(
SELECT *,
RemoveNumericCharacters(RAM) AS Nums
FROM tbl_spe
)
SELECT *
FROM CTE
WHERE Nums <= 1
Upvotes: 0
Reputation: 1551
SELECT *
FROM tbl_spe
WHERE RAM LIKE '[1-9]GB%'
OR RAM LIKE '___MB%'
Upvotes: 0