PDA

View Full Version : Help! Cách tìm kiếm trong SQL giống như toán tử OR trong google !



sillydragon_psd
01-03-2011, 10:53
Hiện mình đang cần hàm tìm kiếm dữ liệu , ví dụ như nhập 2 tên vô 'Lan or Trúc' thì nó sẽ tìm được những người có tên Lan và Trúc ! Mong các bác giúp mình nha ! Cám ơn mọi người nhiều !

vietsol.net
01-03-2011, 11:18
Bạn lên google search fulltext index nhé. Search theo kiểu Match Against làm được điều này rất tốt.

megaownage
01-03-2011, 12:18
Viết một function đổi text string 'Lan or Trúc' thành array (hoặc table), dùng từ 'or' làm mức ngăn (delimiter)
Dùng search IN

select * from BangTen where ten IN HamDoi('Lan or Trúc')

sillydragon_psd
01-03-2011, 13:16
cái này dể mà bạn chỉ vào ô search gỏ tên là ra ngay , nếu bạn muốn truy xuất ra màn hinh thì phải có câu lệnh cái này để mình xem lại 1 chút đã


Bạn lên google search fulltext index nhé. Search theo kiểu Match Against làm được điều này rất tốt.


Viết một function đổi text string 'Lan or Trúc' thành array (hoặc table), dùng từ 'or' làm mức ngăn (delimiter)
Dùng search IN

select * from BangTen where ten IN HamDoi('Lan or Trúc')

Thanks mấy bro ! Mặc dù mình chưa hiểu lắm :( !

megaownage
01-03-2011, 14:20
cái hàm đổi nó đại khái như vầy

(code chôm trên techrepublic - By Tim Chapman June 6, 2008, 11:41 AM PDT)



CREATE FUNCTION [dbo].[udf_PivotParameters]
(
@ParamaterList VARCHAR(MAX),
@Delimiter CHAR(1)
)
RETURNS @ReturnList TABLE
(
FieldValue VARCHAR(MAX)
)
AS BEGIN
DECLARE @ArrayList TABLE
(
FieldValue VARCHAR(MAX)
)
DECLARE @Value VARCHAR(MAX)
DECLARE @CurrentPosition INT

SET @ParamaterList = LTRIM(RTRIM(@ParamaterList))
+ CASE WHEN RIGHT(@ParamaterList, 1) = @Delimiter THEN ''
ELSE @Delimiter
END
SET @CurrentPosition = ISNULL(CHARINDEX(@Delimiter, @ParamaterList, 1), 0)

IF @CurrentPosition = 0
INSERT INTO @ArrayList ( FieldValue )
SELECT @ParamaterList
ELSE
BEGIN
WHILE @CurrentPosition > 0
BEGIN
SET @Value = LTRIM(RTRIM(LEFT(@ParamaterList,
@CurrentPosition - 1))) --make sure a value exists between the delimiters
IF LEN(@ParamaterList) > 0
AND @CurrentPosition <= LEN(@ParamaterList)
BEGIN
INSERT INTO @ArrayList ( FieldValue )
SELECT @Value
END
SET @ParamaterList = SUBSTRING(@ParamaterList,
@CurrentPosition
+ LEN(@Delimiter),
LEN(@ParamaterList))
SET @CurrentPosition = CHARINDEX(@Delimiter,
@ParamaterList, 1)
END
END
INSERT @ReturnList ( FieldValue )
SELECT FieldValue
FROM @ArrayList
RETURN
END

Cách dùng:

DECLARE @ArrayList VARCHAR(MAX)

SET @ArrayList = replace('Mai or Lan or Cúc or Trúc', 'or', ',')
-- hàm chỉ nhận delimiter là char nên cần đổi 'or' thành dấu phẩy

SELECT * FROM DanhSach WHERE Ten IN
( SELECT * FROM dbo.udf_PivotParameters(@ArrayList, ',') )

tb. đừng gọi tôi là bro. Ở thế hệ tôi tiếng này chỉ dùng cho bóng

Red Devilic
01-03-2011, 14:43
Bạn cũng không nhất thiết phải dùng List hay Array hoặc hàm Split.

Có thể đơn giản như sau. Nếu delimiter là dấu, chuỗi là "A,B,C,D,E"

Thêm dấu , ở hai bên thành ",A,B,C,D,E,"

Sử dụng CHARINDEX để SELECT ra những bản ghi nào có "," + Ten + "," xuất hiện trong chuỗi.

Với trường hợp delimiter là "OR" thì cũng tương tự :)

sillydragon_psd
01-03-2011, 14:44
cái hàm đổi nó đại khái như vầy

(code chôm trên techrepublic - By Tim Chapman June 6, 2008, 11:41 AM PDT)



CREATE FUNCTION [dbo].[udf_PivotParameters]
(
@ParamaterList VARCHAR(MAX),
@Delimiter CHAR(1)
)
RETURNS @ReturnList TABLE
(
FieldValue VARCHAR(MAX)
)
AS BEGIN
DECLARE @ArrayList TABLE
(
FieldValue VARCHAR(MAX)
)
DECLARE @Value VARCHAR(MAX)
DECLARE @CurrentPosition INT

SET @ParamaterList = LTRIM(RTRIM(@ParamaterList))
+ CASE WHEN RIGHT(@ParamaterList, 1) = @Delimiter THEN ''
ELSE @Delimiter
END
SET @CurrentPosition = ISNULL(CHARINDEX(@Delimiter, @ParamaterList, 1), 0)

IF @CurrentPosition = 0
INSERT INTO @ArrayList ( FieldValue )
SELECT @ParamaterList
ELSE
BEGIN
WHILE @CurrentPosition > 0
BEGIN
SET @Value = LTRIM(RTRIM(LEFT(@ParamaterList,
@CurrentPosition - 1))) --make sure a value exists between the delimiters
IF LEN(@ParamaterList) > 0
AND @CurrentPosition <= LEN(@ParamaterList)
BEGIN
INSERT INTO @ArrayList ( FieldValue )
SELECT @Value
END
SET @ParamaterList = SUBSTRING(@ParamaterList,
@CurrentPosition
+ LEN(@Delimiter),
LEN(@ParamaterList))
SET @CurrentPosition = CHARINDEX(@Delimiter,
@ParamaterList, 1)
END
END
INSERT @ReturnList ( FieldValue )
SELECT FieldValue
FROM @ArrayList
RETURN
END

Cách dùng:

DECLARE @ArrayList VARCHAR(MAX)

SET @ArrayList = replace('Mai or Lan or Cúc or Trúc', 'or', ',')
-- hàm chỉ nhận delimiter là char nên cần đổi 'or' thành dấu phẩy

SELECT * FROM DanhSach WHERE Ten IN
( SELECT * FROM dbo.udf_PivotParameters(@ArrayList, ',') )

tb. đừng gọi tôi là bro. Ở thế hệ tôi tiếng này chỉ dùng cho bóng

Thanks Anh !
Em đã thử
SELECT * FROM dbo.udf_PivotParameters('thai,hien,sinh', ','))
cái này thì nó ra được là 1 cột có 3 dòng

thai
hien
sinh

nhưng khi kết hợp với câu này thì không có kết quả gì. Theo em nghĩ chắc nó tìm theo chính xác , vậy còn tìm theo có chữ đó là hiện ra thì sao hả anh ?

SELECT * FROM BadgeHistoryTable WHERE LastName in
( SELECT * FROM dbo.udf_PivotParameters('thai,hien,sinh', ','))

Mong được anh trả lời :) !

megaownage
01-03-2011, 15:00
1. LastName là họ chứ đâu phải tên!

2. Nếu chỉ tìm chứa thì có lẽ phải dùng dynamic SQL. Re. Red Devilic

bổ túc thêm

Tìm ra rồi. Làm như vầy

SELECT a.* FROM BadgeHistoryTable a
INNER JOIN ( SELECT * FROM dbo.udf_PivotParameters('thai,hien,sinh', ',')) b
ON LOWER(a.LastName) like '%'+b.FieldValue+'%'

Tất cả những người mà LastName có thai, hien hoặc sinh sẽ hiện ra - kể cả những người tên thien, thieng (chú ý hàm lower)

sillydragon_psd
01-03-2011, 15:05
1. LastName là họ chứ đâu phải tên!

2. Nếu chỉ tìm chứa thì có lẽ phải dùng dynamic SQL. Re. Red Devilic

Tại cái cột đó trong dữ liệu của công ty nó để vậy ! Nhưng trong đó chứa đầy đủ full name :) ! Khó ghê nhỉ :| !

megaownage
01-03-2011, 15:20
@sillydragon_psd: xem lại bài post trước, có bổ túc

sillydragon_psd
02-03-2011, 08:05
@sillydragon_psd: xem lại bài post trước, có bổ túc

Cám ơn anh nhiều lắm ! Em đã làm được rồi ! Nếu anh biết luôn cái Min Max bên chủ đề kia thì giúp em lun nhé ! :) !