列中多个值和范围的 SQL SELECT 查询
Posted
技术标签:
【中文标题】列中多个值和范围的 SQL SELECT 查询【英文标题】:SQL SELECT Query for Multiple Values and Ranges in Column 【发布时间】:2013-05-22 14:10:39 【问题描述】:SQL SELECT 查询给定列的行数据中的多个值和范围。
问题描述:
服务器:mysql
数据库:Customer
表:Lan
列:Allowed VLAN
(范围 1-4096)
Allowed VLAN
列中的一行数据如下:180,181,200,250-499,550-811,826-mismatched
我需要一个SELECT
语句WHERE
列Allowed VLAN
包括一个给定的数字,例如'600'
。给定的数字'600'
甚至是逗号分隔值之一或包含在“250-499”、“550-811”的任何范围内,或者它只是“826-mismatched”范围的起始数字值。
SELECT * WHERE `Allowed VLAN`='600' OR `Allowed VLAN` LIKE '%600%' OR (`Allowed VLAN` BETWEEN '1-1' AND '1-4096');
我无法弄清楚如何使用 WHERE 子句处理数据范围。我已经使用explode() 拆分函数等解决了php 代码的问题,但我认为有一些SQL SELECT 解决方案。
如果能提供任何帮助,我将不胜感激。
【问题讨论】:
我能给你的最好建议是修复你的数据结构。允许的值应位于单独的表中,每个范围或单个值有不同的行。 是的,这是正确的,数据结构很奇怪。数据库设计不是我的,来自客户方面,不确定他们是否会改变它。 【参考方案1】:我强烈建议您规范化您的数据。将逗号分隔的项目列表存储在一行中通常不是一个好主意。
假设您可以进行这样的更改,那么这样的事情应该适合您(尽管您可以考虑将您的范围存储在不同的列中以使其更容易):
create table lan (allowedvan varchar(100));
insert into lan values
('180'),('181'),('200'),('250-499'),('550-811'),('826-mismatched');
select *
from lan
where allowedvan = '600'
or
(instr(allowedvan,'-') > 0 and
'600' >= left(allowedvan,instr(allowedvan,'-')-1) and
'600' <= right(allowedvan,length(allowedvan)-instr(allowedvan,'-'))
)
SQL Fiddle Demo
这使用INSTR
来确定值是否包含范围(连字符),然后使用LEFT
和RIGHT
来获取范围。不要使用LIKE
,因为这可能会返回不准确的结果(例如,600 就像 1600)。
如果您无法更改数据库,则可以考虑使用拆分功能(在 SO 上有几个帖子),然后您可以执行类似于上述方法的操作。
【讨论】:
感谢@sgeddes 提供的解决方案,数据库设计来自客户端,因此不确定他们是否会遵循更改数据结构的原因。当然,我必须尝试将此解决方案与拆分功能混合使用。另外,感谢提及 LIKE 误用。以上是关于列中多个值和范围的 SQL SELECT 查询的主要内容,如果未能解决你的问题,请参考以下文章