سؤال

أنا لا أفعل الكثير من SQL، ومعظم الوقت، أقوم بعمليات CRUD. في بعض الأحيان سأحصل على شيء أكثر تعقيدا قليلا. لذلك، قد يكون هذا السؤال سؤال مبتدئ، لكنني مستعد. لقد كنت أحاول فقط معرفة ذلك لساعات، ولم يتم استخدامها.

لذلك، تخيل هيكل الجدول التالي:

> | ID | Col1 | Col2 | Col3 | .. | Col8 |

أريد أن حدد المعرف وعمود محسوب. يحتوي العمود المحسوب على نطاق من 0 إلى 8 ويحتوي على عدد التطابقات للاستعلام. أريد أيضا تقييد النتيجة التي تم تعيينها لا تشمل فقط الصفوف التي تحتوي على عدد معين من التطابقات.

لذلك، من هذه البيانات العينة:

> | 1 | 'a' | 'b' | 1 | 2 |  
> | 2 | 'b' | 'c' | 1 | 2 |  
> | 3 | 'b' | 'c' | 4 | 5 |  
> | 4 | 'x' | 'x' | 9 | 9 |  

أريد الاستعلام عن COL1 = 'a' أو col2 = 'c' أو col3 = 1 أو col4 = 5 حيث النتيجة المحسوبة> 1 ولها مجموعة النتائج تبدو وكأنها:

> | ID | Cal |
> | 1  |  2  |
> | 2  |  2  |
> | 3  |  2  |

أنا أستخدم T-SQL و SQL Server 2005، إذا كان يهم، ولا يمكنني تغيير مخطط DB.

أفضل أيضا الاحتفاظ به كاستعلام واحدا موجودا وليس من الضروري إنشاء إجراء مخزن أو جدول مؤقت.

هل كانت مفيدة؟

المحلول

ستعمل هذه الإجابة مع SQL 2005، باستخدام CTE لتنظيف الجدول المشتق قليلا.

WITH Matches AS
(
    SELECT ID, CASE WHEN Col1 = 'a' THEN 1 ELSE 0 END + 
                CASE WHEN Col2 = 'c' THEN 1 ELSE 0 END +
                CASE WHEN Col3 = 1  THEN 1 ELSE 0 END +
                CASE WHEN Col4 = 5  THEN 1 ELSE 0 END AS Result
    FROM Table1
    WHERE Col1 = 'a' OR Col2 = 'c' OR Col3 = 1 OR Col4 = 5 
)
SELECT ID, Result
FROM Matches
WHERE Result > 1 

نصائح أخرى

إليك حلا يرفع حقيقة أن مقارنة منطقية إرجاع الأعداد الصحيحة 1 أو 0:

SELECT * FROM (
  SELECT ID, (Col1='a') + (Col2='c') + (Col3=1) + (Col4=5) AS calculated
  FROM MyTable
) q
WHERE calculated > 1; 

لاحظ أنه يجب عليك قوس المقارنات المنطقية + لها أسبقية أعلى من =. وبعد أيضا، عليك أن تضع كل شيء في موقع فرعي لأنك لا تستطيع عادة استخدام اسم مستعار العمود في WHERE جملة من نفس الاستعلام.

قد يبدو أنك يجب أن تستخدم أيضا WHERE جملة في Sacquery لتقييد صفوفها، ولكن في كل الاحتمالات التي ستنتهي بها من خلال مسح جدول كامل على أي حال، لذلك ربما لا يفوز كبير. من ناحية أخرى، إذا كنت تتوقع أن يكون هذا القيد الى حد كبير تقليل عدد الصفوف في النتيجة الفرعية، ثم يكون من المفيد.


إعادة تعليق Quassnoi، إذا لم تتمكن من علاج التعبيرات المنطقية كقيم عدد صحيح، فينبغي أن تكون هناك طريقة لتعيين الظروف المنطقية للأعداد الصحيحة، حتى لو كان الأمر حرفيا بعض الشيء. علي سبيل المثال:

SELECT * FROM (
  SELECT ID, 
      CASE WHEN Col1='a' THEN 1 ELSE 0 END
    + CASE WHEN Col2='c' THEN 1 ELSE 0 END 
    + CASE WHEN Col3=1   THEN 1 ELSE 0 END
    + CASE WHEN Col4=5   THEN 1 ELSE 0 END AS calculated
  FROM MyTable
) q
WHERE calculated > 1;

هذا الاستعلام هو أكثر ودية المؤشر:

SELECT  id, SUM(match)
FROM    (
        SELECT  id, 1 AS match
        FROM    mytable
        WHERE   col1 = 'a'
        UNION ALL
        SELECT  id, 1 AS match
        FROM    mytable
        WHERE   col2 = 'c'
        UNION ALL
        SELECT  id, 1 AS match
        FROM    mytable
        WHERE   col3 = 1
        UNION ALL
        SELECT  id, 1 AS match
        FROM    mytable
        WHERE   col4 = 5
        ) q
GROUP BY
        id
HAVING  SUM(match) > 1

هذا سيكون فعالا فقط إذا الكل الأعمدة التي تبحث عنها هي، أولا، مفهرسة، ثانيا، لها كرادة عالية (العديد من القيم المميزة).

راجع هذه المقالة في مدونتي للحصول على تفاصيل الأداء:

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top