我在表格中有一列,其中此列名称为项,其中包含的值类似
itemID items
1 school,college
2 place, country
3 college,cricket
4 School,us,college
5 cricket,country,place
6 football,tennis,place
7 names,tennis,cricket
8 sports,tennis
现在我需要编写一个搜索查询
例如:如果用户在文本框中键入“板球”并点击按钮,我需要在项栏中查看板球。
在表格中,我在项目列中有3行cricket
(ItemId = 3,5,7)
如果用户键入tennis,cricket
,那么我需要获取与其中任何一个匹配的记录。所以我需要获得5行(ItemId = 3,5,6,7,8)
如何为此要求编写查询?
答案 0 :(得分:5)
您需要从重新设计数据库开始,因为这是一个非常糟糕的结构。您永远不会在字段中存储逗号分隔列表。首先考虑一下你需要的字段,然后设计一个合适的数据库。
答案 1 :(得分:3)
此表的结构非常糟糕(在一列中保存多个值)是您遇到此问题的原因。您最好的选择是规范化表格。
但是如果你不能,那么你可以使用带有通配符的“Like”运算符
Select * From Table
Where items Like '%cricket%'
或
Select * From Table
Where items Like '%cricket%'
or items Like '%tenis%'
您需要从用户输入中动态构造这些sql查询。另一种方法是在服务器上编写代码,将逗号分隔的参数列表转换为表变量或临时表,然后加入它...
答案 2 :(得分:2)
列中的分隔值几乎总是坏表设计。 修复表格结构。
如果由于某种原因你无法做到这一点,你可以期待的最好的是:
SELECT * FROM [MyTable] WHERE items LIKE '%CRICKET%'
这仍然是非常糟糕,原因有两个:
如果您需要帮助修复此结构,解决方案是添加另一个表 - 我们将其称为TableItems
- 您的ItemID列将是原始表的外键和{{ 1}}每个项目值的字段(单数)。然后,您可以加入到该表并完全匹配列值。如果这些项目的工作方式更像是类别,那么您想要使用“Cricket”项目来匹配相同板球项目的行,您还希望第三个表格成为原始表格与其他表格之间的交集我刚刚创造的那个。
答案 3 :(得分:1)
我认为为了数据的有效性,应该对其进行规范化,以便将项目拆分为一个单独的表格,每一行都有一个项目。
在任何一种情况下,这是一个工作示例,它使用用户定义的函数将传入的字符串拆分为表变量,然后将JOIN
与LIKE
CREATE FUNCTION dbo.udf_ItemParse
(
@Input VARCHAR(8000),
@Delimeter char(1)='|'
)
RETURNS @ItemList TABLE
(
Item VARCHAR(50) ,
Pos int
)
AS
BEGIN
DECLARE @Item varchar(50)
DECLARE @StartPos int, @Length int
DECLARE @Pos int
SET @Pos = 0
WHILE LEN(@Input) > 0
BEGIN
SET @StartPos = CHARINDEX(@Delimeter, @Input)
IF @StartPos < 0 SET @StartPos = 0
SET @Length = LEN(@Input) - @StartPos - 1
IF @Length < 0 SET @Length = 0
IF @StartPos > 0
BEGIN
SET @Pos = @Pos + 1
SET @Item = SUBSTRING(@Input, 1, @StartPos - 1)
SET @Input = SUBSTRING(@Input, @StartPos + 1, LEN(@Input) - @StartPos)
END
ELSE
BEGIN
SET @Pos = @Pos+1
SET @Item = @Input
SET @Input = ''
END
INSERT @ItemList (Item, Pos) VALUES(@Item, @Pos)
END
RETURN
END
GO
DECLARE @Itemstable TABLE
(
ItemId INT,
Items VarChar (1000)
)
INSERT INTO @Itemstable
SELECT 1 itemID, 'school,college' items UNION
SELECT 2, 'place, country' UNION
SELECT 3, 'college,cricket' UNION
SELECT 4, 'School,us,college' UNION
SELECT 5, 'cricket,country,place' UNION
SELECT 6, 'footbal,tenis,place' UNION
SELECT 7, 'names,tenis,cricket' UNION
SELECT 8, 'sports,tenis'
DECLARE @SearchParameter VarChar (100)
SET @SearchParameter = 'cricket'
SELECT DISTINCT ItemsTable.*
FROM @Itemstable ItemsTable
INNER JOIN udf_ItemParse (@SearchParameter, ',') udf
ON ItemsTable.Items LIKE '%' + udf.Item + '%'
SET @SearchParameter = 'cricket,tenis'
SELECT DISTINCT ItemsTable.*
FROM @Itemstable ItemsTable
INNER JOIN udf_ItemParse (@SearchParameter, ',') udf
ON ItemsTable.Items LIKE '%' + udf.Item + '%'
答案 4 :(得分:1)
对于单个项目:
SELECT itemID, items FROM MyTable WHERE items LIKE '%cricket%'
对于多个项目:
SELECT itemID, items FROM MyTable WHERE items LIKE '%tennis%' or items LIKE '%cricket%'
您需要解析输入并将其拆分并将每个项目添加到查询中:
items LIKE '%item1%' or items LIKE '%item2%' or items LIKE '%item3%' ...
答案 5 :(得分:0)
为什么你首先使用的是数据库?
我的意思是:你显然没有使用它的潜力。如果你喜欢用逗号分隔的东西,试试一个文件。
答案 6 :(得分:0)
在MySQL
中,在表格上创建全文索引:
CREATE FULLTEXT INDEX fx_mytable_items ON mytable (items)
并发出此查询:
SELECT *
FROM mytable
WHERE MATCH(items) AGAINST ('cricket tennis' IN BOOLEAN MODE)