2013-04-30 15 views
5

Ho una tabella in SQL Server chiamato tbl_spe che contiene alcune specifiche di un computer come CPU, RAM,... voglio selezionare tutte le righe con questa condizione: tutte le righe che la loro RAM sono meno di 1 GB Possiamo semplicemente scrivere questa query:Selezionare da questa tabella

Select * from tbl_spe where RAM <= 1 

O qualcosa del genere, ma il problema è sui dati della tabella:

ID RAM 

159 2GB DDR2 
160 256MB DDR 
161 3GB DDR2 
162 512MB DDR 

Come posso estrarre parte del numero del campo RAM? e dire di interrogare selezionare tutte le righe che la loro RAM sia inferiore a 1GB?

+4

Sarebbe meglio cambiare il vostro disegno in modo che la quantità * * di RAM è tenuto in un campo e il * tipo * di RAM in un altro. Quindi trovare i computer con meno di 1 GB di RAM sarà banale. Inoltre, prova a non scrivere query 'select * from'; recupera invece solo i campi di cui hai bisogno. –

+0

I secondo suggerimento di Newman. Avere un campo numerico separato sarà migliore in termini di prestazioni selezionate in quanto non dovrai fare tutto ciò che riguarda la manipolazione delle stringhe. Inoltre, puoi aggiungere un campo 'unit' in modo da poter eseguire la conversione. Il campo unità può avere 'MB' o' GB', ecc. Quindi probabilmente è possibile avere una tabella di unità e assegnare valori per ogni unità e rapporto in modo da poter eseguire la conversione in un secondo momento. –

+0

Sono nuovamente d'accordo a suddividere il valore in campi separati. Tuttavia so che a volte non è fattibile, infatti mi sono imbattuto in un problema simile recentemente, quindi la mia risposta qui sotto. – XN16

risposta

5
;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' 

Ecco un esempio in SQLFiddle

Se si voleva avere meno di 2GB quindi modificare la clausola WHERE a questo:

WHERE RAMFactor = 'MB' 
    OR (RAMFactor = 'GB' AND RAMValue < 2) 

Il primo controllo ottiene tutti i record misurati in "MB", quindi inferiori a "GB". Il secondo controllo otterrà tutti i record misurati in "GB" e avranno un valore inferiore a 2, quindi valori "GB" inferiori a 2 GB.

+0

Sebbene questa sia una soluzione di bell'aspetto, credo che includerà il valore 'GB'. –

+0

@vonv. Funziona: [SQLFiddle] (http://sqlfiddle.com/#!3/9680f/1) – XN16

+0

Questo non era il codice che ho visto prima. Sì, ora sembra che funzionerà, senza andare al sqlfiddle. Farò +1 così altri, specialmente l'OP, non saranno fuorviati dal mio commento. –

4
SELECT * FROM tbl_spe 
WHERE CAST(SUBSTRING(RAM,0,PATINDEX('%[a-zA-Z]%',RAM)) AS INT) <=1 

PATINDEX('%[a-zA-Z]%',RAM) rileva la posizione del primo alfabeto e funzione SUBSTRING estratti numero da stringa.

MODIFICA: Sotto la query prende in considerazione la RAM in MB e GB. In caso contrario, al di sopra query restituisce in modo errato 256 MB di RAM superiore a 1 GB

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%') 
+2

C'è un problema con questa risposta. Questo non funzionerà con i valori con DDR. –

+1

@von v. Sì, ho perso l'esempio DDR. Ora corretto +1 a voi signore. –

0
SELECT * 
FROM tbl_spe 
WHERE RAM LIKE '[1-9]GB%' 
OR RAM LIKE '___MB%' 
0

due fasi:

1) esegue una funzione personalizzata per estrarre solo i valori numerici da RAM colonna.

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) E secondo passo, è sufficiente utilizzare la funzione

WITH CTE 
AS 
(
    SELECT *, 
      RemoveNumericCharacters(RAM) AS Nums 
    FROM tbl_spe 
) 

SELECT * 
FROM CTE 
WHERE Nums <= 1 
1

Beh io ho attraversato lo stesso problema così ho creato il mio propria funzione per questo (ovviamente ho avuto qualche aiuto dai miei amici in Internet) è la funzione: valore

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 
4

ho preso (dimensione) parte estrazione di campo RAM utilizzando @ XN16 query e utilizzato CASE condizione nella clausola WHERE applicare la condizione in base alla dimensione indicata.

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 precedenza CASE condizioni, è possibile aggiungere il caso di KB e aggiungere la logica per ottenere GB dalla data dimensione di KB .....

Partenza SQLFIDDLE

Problemi correlati