تصفية مع متعدد حدد مربعات مع SQL Server
-
03-07-2019 - |
سؤال
وأحتاج لتصفية مجموعات النتائج من خادم SQL استنادا إلى التحديدات من مربع قائمة متعدد حدد. لقد تم من خلال فكرة القيام على instring لتحديد ما إذا كان وجود قيمة صف في قيم التصفية المحدد، ولكن هذا عرضة للمطابقة الجزئية (مثل السيارات مباريات السجاد).
وذهبت أيضا من خلال تقسيم السلسلة إلى طاولة وانضمامه / المطابقة بناء على ذلك، ولكن لدي تحفظات حول كيفية أن يجري القيام بها.
وكما نرى هذه مهمة تبدو مشتركة، وأنا أبحث في المجتمع المكدس تجاوز لبعض ردود الفعل وربما بضعة اقتراحات حول المنهج الأكثر استخداما عادة في حل هذه المشكلة.
المحلول
وأنا تحل هذه واحدة من خلال كتابة دالة قيم الجدول (نستخدمه 2005) التي تأخذ سلسلة محددة وإرجاع الجدول. ثم يمكنك الانضمام إلى هذا أو استخدام حيث يوجد أو حيث X IN. لم نقم اختبار التحمل الكامل بعد، ولكن مع استخدام محدود ومجموعات صغيرة بشكل معقول من البنود أعتقد أن الأداء ينبغي أن تكون على ما يرام.
وفيما يلي واحدة من المهام كنقطة انطلاق بالنسبة لك. ولدي أيضا واحدة مكتوبة خصيصا لقبول قائمة محددة من [إينتس] للقيم ID في جداول البحث، وما إلى ذلك.
والاحتمال الآخر هو أن استخدام مثل مع المحددات للتأكد من أن المباريات الجزئية لتجاهل، ولكن لا يمكنك استخدام المؤشرات مع ذلك، لذلك سوف يكون الأداء الضعيف للأي جدول كبير. على سبيل المثال:
SELECT
my_column
FROM
My_Table
WHERE
@my_string LIKE '%|' + my_column + '|%'
/*
Name: GetTableFromStringList
Description: Returns a table of values extracted from a delimited list
Parameters:
@StringList - A delimited list of strings
@Delimiter - The delimiter used in the delimited list
History:
Date Name Comments
---------- ------------- ----------------------------------------------------
2008-12-03 T. Hummel Initial Creation
*/
CREATE FUNCTION dbo.GetTableFromStringList
(
@StringList VARCHAR(1000),
@Delimiter CHAR(1) = ','
)
RETURNS @Results TABLE
(
String VARCHAR(1000) NOT NULL
)
AS
BEGIN
DECLARE
@string VARCHAR(1000),
@position SMALLINT
SET @StringList = LTRIM(RTRIM(@StringList)) + @Delimiter
SET @position = CHARINDEX(@Delimiter, @StringList)
WHILE (@position > 0)
BEGIN
SET @string = LTRIM(RTRIM(LEFT(@StringList, @position - 1)))
IF (@string <> '')
BEGIN
INSERT INTO @Results (String) VALUES (@string)
END
SET @StringList = RIGHT(@StringList, LEN(@StringList) - @position)
SET @position = CHARINDEX(@Delimiter, @StringList, 1)
END
RETURN
END
نصائح أخرى
ولقد تم من خلال فكرة القيام ل instring لتحديد ما إذا كانت قيمة التوالي موجود في القيم التصفية المحدد، ولكن هذا عرضة للمطابقة الجزئية (مثل السيارات مباريات السجاد)
اقتباس فقرة>ويبدو لي كما لو كنت لا بما في ذلك هوية فريدة من نوعها، أو ربما المفتاح الأساسي كجزء من القيم في مربع القائمة الخاصة بك. ومن الناحية المثالية كل خيار سيكون له معرف فريد يطابق عمود في الجدول كنت تبحث عن. إذا كان مربع القائمة الخاصة بك مثل أدناه ثم هل سيكون قادرا على تصفية خصيصا لسيارات لأنك سوف تحصل على قيمة فريدة 3.
<option value="3">Car</option>
<option value="4">Carpret</option>
وبعد ذلك يمكنك فقط بناء على بند حيث من شأنها أن تسمح لك العثور على القيم التي تحتاج إليها.
والتحديث، للإجابة على تعليق.
<اقتباس فقرة>وكيف يمكن أن أفعل ذات الصلة الانضمام بالنظر إلى أن يمكن للمستخدم اختيار وعدد التعسفي من الخيارات مربع القائمة؟ * اختر من tblTable التسجيل tblOptions ON tblTable.FK =؟ ال المشكلة هنا هي أن أحتاج للانضمام ل قيم متعددة.
اقتباس فقرة>وأجبت مماثلة السؤال هنا أ >.
وأسلوب واحد سيكون لبناء جدول مؤقت وإضافة كل الخيار المحدد كصف إلى الجدول المؤقت. ثم كنت ببساطة القيام الانضمام إلى الجدول المؤقت.
إذا كنت تريد ببساطة إنشاء SQL بشكل حيوي يمكنك أن تفعل شيئا من هذا القبيل.
SELECT * FROM tblTable WHERE option IN (selected_option_1, selected_option_2, selected_option_n)
ولقد وجدت أن دالة قيم الجدول CLR التي تأخذ سلسلة الخاص بك محددة ويدعو سبليت في سلسلة (اعادة مجموعة باسم IEnumerable) هو أكثر performant للمن أي شيء مكتوب في T-SQL (ويبدأ لكسر عندما لديك حوالي مليون العناصر في القائمة محددة، ولكن هذا أبعد من ذلك بكثير من من الحل T-SQL).
وبعد ذلك، هل يمكن الانضمام على الطاولة أو تحقق مع موجودا.