Ik heb een select nodig die resultaten als deze zou opleveren:
SELECT * FROM MyTable WHERE Column1 CONTAINS 'word1 word2 word3'
En ik heb alle resultaten nodig, d.w.z. dit omvat tekenreeksen met ‘woord2 woord3 woord1’ of ‘woord1 woord3 woord2’ of een andere combinatie van de drie.
Alle woorden moeten in het resultaat voorkomen.
Antwoord 1, autoriteit 100%
Vrij trage, maar werkwijze om elk van woorden op te nemen:
SELECT * FROM mytable
WHERE column1 LIKE '%word1%'
OR column1 LIKE '%word2%'
OR column1 LIKE '%word3%'
Als je alle woorden nodig hebt om aanwezig te zijn, gebruik dan dit:
SELECT * FROM mytable
WHERE column1 LIKE '%word1%'
AND column1 LIKE '%word2%'
AND column1 LIKE '%word3%'
Als je iets sneller wilt, moet je zoeken in volledige tekst, en dit is heel specifiek voor elk databasetype.
Antwoord 2, autoriteit 9%
Houd er rekening mee dat als u LIKE
gebruikt om te bepalen of een tekenreeks een subtekenreeks is van een andere tekenreeks, u moet ontsnappen aan de patroonovereenkomstige tekens in uw zoekreeks.
Als uw SQL-dialect CHARINDEX
ondersteunt, is het een stuk eenvoudiger om het te gebruiken:
SELECT * FROM MyTable
WHERE CHARINDEX('word1', Column1) > 0
AND CHARINDEX('word2', Column1) > 0
AND CHARINDEX('word3', Column1) > 0
Houd er ook rekening mee dat deze en de methode in het geaccepteerde antwoord alleen betrekking hebben op substring-matching in plaats van op woord-matching. Dus bijvoorbeeld de tekenreeks 'word1word2word3'
zou nog steeds overeenkomen.
Antwoord 3, autoriteit 2%
Functie
CREATE FUNCTION [dbo].[fnSplit] ( @sep CHAR(1), @str VARCHAR(512) )
RETURNS TABLE AS
RETURN (
WITH Pieces(pn, start, stop) AS (
SELECT 1, 1, CHARINDEX(@sep, @str)
UNION ALL
SELECT pn + 1, stop + 1, CHARINDEX(@sep, @str, stop + 1)
FROM Pieces
WHERE stop > 0
)
SELECT
pn AS Id,
SUBSTRING(@str, start, CASE WHEN stop > 0 THEN stop - start ELSE 512 END) AS Data
FROM
Pieces
)
Zoekopdracht
DECLARE @FilterTable TABLE (Data VARCHAR(512))
INSERT INTO @FilterTable (Data)
SELECT DISTINCT S.Data
FROM fnSplit(' ', 'word1 word2 word3') S -- Contains words
SELECT DISTINCT
T.*
FROM
MyTable T
INNER JOIN @FilterTable F1 ON T.Column1 LIKE '%' + F1.Data + '%'
LEFT JOIN @FilterTable F2 ON T.Column1 NOT LIKE '%' + F2.Data + '%'
WHERE
F2.Data IS NULL
Antwoord 4
In plaats van SELECT * FROM MyTable WHERE Column1 CONTAINS 'word1 word2 word3'
,
add En tussen die woorden als:
SELECT * FROM MyTable WHERE Column1 CONTAINS 'word1 And word2 And word3'
voor details, zie hier
https://msdn.microsoft.com/en-us/library/ms187787.aspx
UPDATE
Gebruik voor het selecteren van zinnen dubbele aanhalingstekens, zoals:
SELECT * FROM MyTable WHERE Column1 CONTAINS '"Phrase one" And word2 And "Phrase Two"'
ps u moet eerst Full Text Search inschakelen in de tabel voordat u het trefwoord bevat. voor meer details, zie hier https://docs.microsoft.com/en-us/sql/relational-databases/search/get-started-with-full-text-search
Antwoord 5
SELECT * FROM MyTable WHERE
Column1 LIKE '%word1%'
AND Column1 LIKE '%word2%'
AND Column1 LIKE '%word3%'
OR
gewijzigd in AND
op basis van bewerken van vraag.
Antwoord 6
Als u Oracle Database gebruikt, kunt u dit bereiken met bevat zoekopdracht. Bevat zoekopdrachten zijn sneller dan soortgelijke zoekopdrachten.
Als je alle woorden nodig hebt
SELECT * FROM MyTable WHERE CONTAINS(Column1,'word1 and word2 and word3', 1) > 0
Als je een van de woorden nodig hebt
SELECT * FROM MyTable WHERE CONTAINS(Column1,'word1 or word2 or word3', 1) > 0
Bevat een behoefteindex van het type CONTEXT in uw kolom.
CREATE INDEX SEARCH_IDX ON MyTable(Column) INDEXTYPE IS CTXSYS.CONTEXT
Antwoord 7
Als je gewoon een match wilt vinden.
SELECT * FROM MyTable WHERE INSTR('word1 word2 word3',Column1)<>0
SQL-server:
CHARINDEX(Column1, 'word1 word2 word3', 1)<>0
Voor een exacte overeenkomst. Voorbeeld (';a;ab;ac;',';b;')
krijgt geen overeenkomst.
SELECT * FROM MyTable WHERE INSTR(';word1;word2;word3;',';'||Column1||';')<>0
Antwoord 8
Een van de gemakkelijkste manieren om te bereiken wat in de vraag wordt genoemd, is door BEVAT met NEAR of ‘~’. De volgende zoekopdrachten geven ons bijvoorbeeld alle kolommen die specifiek woord1, woord2 en woord3 bevatten.
SELECT * FROM MyTable WHERE CONTAINS(Column1, 'word1 NEAR word2 NEAR word3')
SELECT * FROM MyTable WHERE CONTAINS(Column1, 'word1 ~ word2 ~ word3')
Bovendien retourneert CONTAINSTABLE een rangorde voor elk document op basis van de nabijheid van “woord1”, “woord2” en “woord3”. Als een document bijvoorbeeld de zin “Het woord1 is woord2 en woord3” bevat, zou de rangorde hoog zijn omdat de termen dichter bij elkaar liggen dan in andere documenten.
Een ander ding dat ik zou willen toevoegen, is dat we ook proximity_term kunnen gebruiken om kolommen te vinden waar de woorden binnen een bepaalde afstand tussen hen in de kolomzin staan.
Antwoord 9
de beste manier is om een ​​volledige tekstindex te maken voor een kolom in de tabel
en gebruik bevatten in plaats van LIKE
SELECT * FROM MyTable WHERE
contains(Column1 , N'word1' )
AND contains(Column1 , N'word2' )
AND contains(Column1 , N'word3' )
Antwoord 10
waarom niet “in” gebruiken?
Select *
from table
where columnname in (word1, word2, word3)
Antwoord 11
Dit zou idealiter moeten worden gedaan met behulp van de volledige tekstzoekopdracht van de sql-server, indien gebruikt.
Als u dat echter om de een of andere reden niet aan uw DB kunt krijgen, is hier een prestatie-intensieve oplossing: –
-- table to search in
CREATE TABLE dbo.myTable
(
myTableId int NOT NULL IDENTITY (1, 1),
code varchar(200) NOT NULL,
description varchar(200) NOT NULL -- this column contains the values we are going to search in
) ON [PRIMARY]
GO
-- function to split space separated search string into individual words
CREATE FUNCTION [dbo].[fnSplit] (@StringInput nvarchar(max),
@Delimiter nvarchar(1))
RETURNS @OutputTable TABLE (
id nvarchar(1000)
)
AS
BEGIN
DECLARE @String nvarchar(100);
WHILE LEN(@StringInput) > 0
BEGIN
SET @String = LEFT(@StringInput, ISNULL(NULLIF(CHARINDEX(@Delimiter, @StringInput) - 1, -1),
LEN(@StringInput)));
SET @StringInput = SUBSTRING(@StringInput, ISNULL(NULLIF(CHARINDEX
(
@Delimiter, @StringInput
),
0
), LEN
(
@StringInput)
)
+ 1, LEN(@StringInput));
INSERT INTO @OutputTable (id)
VALUES (@String);
END;
RETURN;
END;
GO
-- this is the search script which can be optionally converted to a stored procedure /function
declare @search varchar(max) = 'infection upper acute genito'; -- enter your search string here
-- the searched string above should give rows containing the following
-- infection in upper side with acute genitointestinal tract
-- acute infection in upper teeth
-- acute genitointestinal pain
if (len(trim(@search)) = 0) -- if search string is empty, just return records ordered alphabetically
begin
select 1 as Priority ,myTableid, code, Description from myTable order by Description
return;
end
declare @splitTable Table(
wordRank int Identity(1,1), -- individual words are assinged priority order (in order of occurence/position)
word varchar(200)
)
declare @nonWordTable Table( -- table to trim out auxiliary verbs, prepositions etc. from the search
id varchar(200)
)
insert into @nonWordTable values
('of'),
('with'),
('at'),
('in'),
('for'),
('on'),
('by'),
('like'),
('up'),
('off'),
('near'),
('is'),
('are'),
(','),
(':'),
(';')
insert into @splitTable
select id from dbo.fnSplit(@search,' '); -- this function gives you a table with rows containing all the space separated words of the search like in this e.g., the output will be -
-- id
-------------
-- infection
-- upper
-- acute
-- genito
delete s from @splitTable s join @nonWordTable n on s.word = n.id; -- trimming out non-words here
declare @countOfSearchStrings int = (select count(word) from @splitTable); -- count of space separated words for search
declare @highestPriority int = POWER(@countOfSearchStrings,3);
with plainMatches as
(
select myTableid, @highestPriority as Priority from myTable where Description like @search -- exact matches have highest priority
union
select myTableid, @highestPriority-1 as Priority from myTable where Description like @search + '%' -- then with something at the end
union
select myTableid, @highestPriority-2 as Priority from myTable where Description like '%' + @search -- then with something at the beginning
union
select myTableid, @highestPriority-3 as Priority from myTable where Description like '%' + @search + '%' -- then if the word falls somewhere in between
),
splitWordMatches as( -- give each searched word a rank based on its position in the searched string
-- and calculate its char index in the field to search
select myTable.myTableid, (@countOfSearchStrings - s.wordRank) as Priority, s.word,
wordIndex = CHARINDEX(s.word, myTable.Description) from myTable join @splitTable s on myTable.Description like '%'+ s.word + '%'
-- and not exists(select myTableid from plainMatches p where p.myTableId = myTable.myTableId) -- need not look into myTables that have already been found in plainmatches as they are highest ranked
-- this one takes a long time though, so commenting it, will have no impact on the result
),
matchingRowsWithAllWords as (
select myTableid, count(myTableid) as myTableCount from splitWordMatches group by(myTableid) having count(myTableid) = @countOfSearchStrings
)
, -- trim off the CTE here if you don't care about the ordering of words to be considered for priority
wordIndexRatings as( -- reverse the char indexes retrived above so that words occuring earlier have higher weightage
-- and then normalize them to sequential values
select s.myTableid, Priority, word, ROW_NUMBER() over (partition by s.myTableid order by wordindex desc) as comparativeWordIndex
from splitWordMatches s join matchingRowsWithAllWords m on s.myTableId = m.myTableId
)
,
wordIndexSequenceRatings as ( -- need to do this to ensure that if the same set of words from search string is found in two rows,
-- their sequence in the field value is taken into account for higher priority
select w.myTableid, w.word, (w.Priority + w.comparativeWordIndex + coalesce(sequncedPriority ,0)) as Priority
from wordIndexRatings w left join
(
select w1.myTableid, w1.priority, w1.word, w1.comparativeWordIndex, count(w1.myTableid) as sequncedPriority
from wordIndexRatings w1 join wordIndexRatings w2 on w1.myTableId = w2.myTableId and w1.Priority > w2.Priority and w1.comparativeWordIndex>w2.comparativeWordIndex
group by w1.myTableid, w1.priority,w1.word, w1.comparativeWordIndex
)
sequencedPriority on w.myTableId = sequencedPriority.myTableId and w.Priority = sequencedPriority.Priority
),
prioritizedSplitWordMatches as ( -- this calculates the cumulative priority for a field value
select w1.myTableId, sum(w1.Priority) as OverallPriority from wordIndexSequenceRatings w1 join wordIndexSequenceRatings w2 on w1.myTableId = w2.myTableId
where w1.word <> w2.word group by w1.myTableid
),
completeSet as (
select myTableid, priority from plainMatches -- get plain matches which should be highest ranked
union
select myTableid, OverallPriority as priority from prioritizedSplitWordMatches -- get ranked split word matches (which are ordered based on word rank in search string and sequence)
),
maximizedCompleteSet as( -- set the priority of a field value = maximum priority for that field value
select myTableid, max(priority) as Priority from completeSet group by myTableId
)
select priority, myTable.myTableid , code, Description from maximizedCompleteSet m join myTable on m.myTableId = myTable.myTableId
order by Priority desc, Description -- order by priority desc to get highest rated items on top
--offset 0 rows fetch next 50 rows only -- optional paging
Antwoord 12
probeer de “tesarus-zoekopdracht” in de volledige tekstindex in MS SQL Server te gebruiken. Dit is veel beter dan het gebruik van “%” bij het zoeken als u miljoenen records heeft. tesarus hebben een kleine hoeveelheid geheugenverbruik dan de anderen.
probeer deze functies te doorzoeken 🙂
Antwoord 13
SELECT * FROM MyTable WHERE Column1 Like "*word*"
Hiermee worden alle records weergegeven waarvan column1
een gedeeltelijke waarde heeft en bevat word
.
Antwoord 14
DECLARE @SearchStr nvarchar(100)
SET @SearchStr = ' '
CREATE TABLE #Results (ColumnName nvarchar(370), ColumnValue nvarchar(3630))
SET NOCOUNT ON
DECLARE @TableName nvarchar(256), @ColumnName nvarchar(128), @SearchStr2 nvarchar(110)
SET @TableName = ''
SET @SearchStr2 = QUOTENAME('%' + @SearchStr + '%','''')
WHILE @TableName IS NOT NULL
BEGIN
SET @ColumnName = ''
SET @TableName =
(
SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @TableName
AND OBJECTPROPERTY(
OBJECT_ID(
QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)
), 'IsMSShipped'
) = 0
)
WHILE (@TableName IS NOT NULL) AND (@ColumnName IS NOT NULL)
BEGIN
SET @ColumnName =
(
SELECT MIN(QUOTENAME(COLUMN_NAME))
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = PARSENAME(@TableName, 2)
AND TABLE_NAME = PARSENAME(@TableName, 1)
AND DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar', 'int', 'decimal')
AND QUOTENAME(COLUMN_NAME) > @ColumnName
)
IF @ColumnName IS NOT NULL
BEGIN
INSERT INTO #Results
EXEC
(
'SELECT ''' + @TableName + '.' + @ColumnName + ''', LEFT(' + @ColumnName + ', 3630) FROM ' + @TableName + ' (NOLOCK) ' +
' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2
)
END
END
END
SELECT ColumnName, ColumnValue FROM #Results
DROP TABLE #Results
Antwoord 15
select * from table where name regexp '^word[1-3]$'
of
select * from table where name in ('word1','word2','word3')