簡體   English   中英

修復SQL where丑陋且令人困惑的語句

[英]Fixing an SQL where statement that is ugly and confusing

我直接查詢后端MS SQL Server的軟件包。 雖然我們在字段中輸入數值,但關鍵字段(車輛編號)被定義為alpha。 這只有一個例外,我們在車輛退役時在號碼前加上“R”(這意味着我們賣掉它或者車輛被廢棄)。 假設用戶這樣做,我們不應該使用此方法遇到問題。 (對或錯不是問題)

快進到現在。 我正在嘗試查詢這些車輛編號的子集(800 - 899)以進行一些特殊處理。 通過做'800'到'899'的范圍,我們也得到80,81等。如果我將車輛編號投入INT,我應該能夠獲得正確的范圍。 除了這些“R”車輛現在踢我的屁股。

我已經嘗試過where vehicleId not like 'R%' and cast(vehicleId as int) between 800 and 899但是,我在其中一輛“R”車輛上出現了投射錯誤。

什么工作是where vehicleId not between '800' and '899' and cast(vehicleId as int) between 800 and 899' ,但我覺得必須有更好的方式和更少混亂的方式。

我還嘗試了HAVING和子查詢的其他變體都產生了投射錯誤。

雖然未經測試,但這應該可以解決問題:

where cast(replace(vehicleId,'R','') as int) between 800 and 899

使用_運算符而不是%運算符:

WHERE vehicleId LIKE 'R8__' OR vehicleId LIKE '8__'

您也可以將它們組合起來:

WHERE vehicleId LIKE '%8__'

無法保證優化器將以正確的順序執行這些(當前SQL中沒有短路評估):

where vehicleId not like 'R%' and cast(vehicleId as int) between 800 and 899 

演員陣容可能會失敗。

嘗試這個:

WHERE
    CASE
        WHEN vehicleId NOT LIKE 'R%' THEN
            CAST(vehicleId as int)
        ELSE
            0
    END BETWEEN 800 AND 899 

這個怎么樣:

WHERE vehicleId BETWEEN '800' and '899' AND LEN(vehicleId) = 3

不是很干凈,但它會消除兩個角色的匹配。

好吧你的問題是你正在嘗試對字符串字段進行數學排序。

嘗試使用派生表來首先排除非數字和tehn將結果數據轉換為int

select * from 
(select * from mytable where vehicleId not like 'R%')a
where cast(vehicleId as int) between 800 and 900

好吧,這不起作用,你可以嘗試select * from(select * from mytable where isnumeric(vehicleId)= 0)a cast(vehicleId as int)在800和900之間

isnumeric存在一些問題,但是如果它有效,你可以編寫一個isint()函數並使用它。

where 1=
(
    case 
        when 
            vehicleId like 'R%' then 0 
        else 
            (case when cast(vehicleId as int) between 800 and 899 then 1 else 0 end) 
    end
)

我不確定您是否希望包含'R%'記錄以及vehicleIds的范圍是否可變,但這可能會有所幫助。

WHERE vehicleId LIKE '8[0-9][0-9]' 
OR vehicleId LIKE 'R8[0-9][0-9]'

如果范圍是變量,那么你可能想要這樣的東西。

WHERE CASE WHEN vehicleId LIKE 'R%' THEN CAST(SUBSTRING(vehicleId,2,99) AS INT)
    WHEN vehicleId LIKE '[0-9][0-9][0-9]' THEN CAST(vehicleId AS INT)
    END BETWEEN 800 AND 899

當我處理這樣的事情時,我會做這樣的事情......

DECLARE @Autos Table  (
ID varchar(100)
)

Insert into @Autos (ID) values ('R1')
Insert into @Autos (ID) values ('2')
Insert into @Autos (ID) values ('3')
Insert into @Autos (ID) values ('R4')
Insert into @Autos (ID) values ('5')
Insert into @Autos (ID) values ('R52')
Insert into @Autos (ID) values ('53')
Insert into @Autos (ID) values ('R8')

Select * from @Autos
Where cast(REPLACE(ID, 'R', '0') as integer) between 2 and 55
and ID not like 'R%'

輸出是,

ID
---
2
3
5
53

--Kris

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM