كيف يمكنني الاستعلام عن جداول SQL متعددة لزوج محدد من قيمة المفتاح؟

StackOverflow https://stackoverflow.com/questions/104230

  •  01-07-2019
  •  | 
  •  

سؤال

الموقف:يقوم تطبيق PHP الذي يحتوي على وحدات متعددة قابلة للتثبيت بإنشاء جدول جديد في قاعدة البيانات لكل منها، بأسلوب mod_A، وmod_B، وmod_C وما إلى ذلك.يحتوي كل منها على العمود section_id.

الآن، أنا أبحث عن جميع الإدخالات الخاصة بـ section_id محدد، وآمل أن تكون هناك طريقة أخرى إلى جانب "Select * from mod_a، mod_b، mod_c...mod_xyzzy حيث section_id=value"...أو الأسوأ من ذلك، استخدام استعلام منفصل لكل وحدة.

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

المحلول

إذا كانت الجداول تتغير بمرور الوقت، فيمكنك تضمين التعليمات البرمجية لإنشاء الحل الخاص بك في SP (رمز زائف - سيتعين عليك ملؤه):

SET @sql = ''

DECLARE CURSOR FOR
SELECT t.[name] AS TABLE_NAME
FROM sys.tables t
WHERE t.[name] LIKE 'SOME_PATTERN_TO_IDENTIFY_THE_TABLES'

-- أو هذا

DECLARE CURSOR FOR
SELECT t.[name] AS TABLE_NAME
FROM TABLE_OF_TABLES_TO_SEACRH t

START LOOP

IF @sql <> '' SET @sql = @sql + 'UNION ALL '
SET @sql = 'SELECT * FROM [' + @TABLE_NAME + '] WHERE section_id=value '

END LOOP

EXEC(@sql)

لقد استخدمت هذه التقنية من حين لآخر، عندما لا توجد طريقة واضحة لجعلها قابلة للاستخدام في المستقبل بدون SQL الديناميكي.

ملحوظة:في حلقتك، يمكنك استخدام خدعة الانتشار COALESCE/NULL وترك السلسلة كـ NULL قبل الحلقة، ولكن ليس من الواضح ما إذا كنت غير معتاد على المصطلح:

SET @sql = COALESCE(@sql + ' UNION ALL ', '')
    + 'SELECT * FROM [' + @TABLE_NAME + '] WHERE section_id=value '

نصائح أخرى

ماذا عن؟

SELECT * FROM mod_a WHERE section_id=value
UNION ALL
SELECT * FROM mod_b WHERE section_id=value
UNION ALL
SELECT * FROM mod_c WHERE section_id=value

لدي اقتراحان.

  1. ربما تحتاج إلى دمج كافة الجداول الخاصة بك.إذا كانت جميعها تحتوي على نفس البنية، فلماذا لا يكون هناك جدول وحدة "رئيسي" واحد، يضيف فقط عمودًا جديدًا يحدد الوحدة ("A"، "B"، "C"، ....)

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

    يفترض هذا الاقتراح أن استعلامك في العمود section_id الذي ذكرته أمر بالغ الأهمية للبحث عنه بسرعة.من خلال استعلام واحد، يمكنك الحصول على كافة المعلومات الشائعة، ومن خلال استعلام آخر يمكنك الحصول على أي معلومات محددة إذا كنت في حاجة إليها.(وربما لا - على سبيل المثال، إذا كنت تحاول التحقق من صحة وجود القسم، فإن العثور عليه في الجدول المشترك سيكون كافيًا)

  2. وبدلاً من ذلك، يمكنك إضافة جدول آخر يقوم بتعيين معرف القسم إلى الوحدات النمطية الموجودة فيه.

    section_id | module
    -----------+-------
          1    |  A
          2    |  B
          3    |  A
         ...   | ...
    

    هذا يعني أنه يتعين عليك تشغيل استعلامين، أحدهما مقابل جدول التعيين هذا، والآخر مقابل جدول الوحدة النمطية لسحب أي بيانات مفيدة.

    يمكنك توسيع هذا الجدول بأعمدة ومؤشرات أخرى في تلك الأعمدة إذا كنت بحاجة إلى البحث عن أعمدة أخرى مشتركة بين جميع الوحدات.

    هذه الطريقة لها عيب واضح وهو تكرار البيانات.

ربما تكون بعض المعلومات الإضافية مفيدة، ولكن يبدو أن الحل لديك بالفعل.سيتعين عليك الاختيار من بين جميع الجداول التي تحتوي على section_id.يمكنك استخدام الصلات بدلاً من قائمة الجداول، والانضمام على section_id.على سبيل المثال

select a.some_field, b.some_field.... 
from mod_a a
inner join mod_b b on a.section_id = b.section_id
...
where a.section_id = <parameter>

يمكنك أيضًا تجميع هذا كعرض.لاحظ أيضًا قائمة الحقول بدلاً من *، والتي أوصي بها إذا كنت تنوي استخدام * بالفعل.

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

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

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

SELECT * FROM (
    SELECT * FROM table1
    UNION ALL
    SELECT * FROM table2
    UNION ALL
    SELECT * FROM table3
) subQry
WHERE field=value

سيكون أحد الخيارات من جانب قاعدة البيانات هو إنشاء طريقة عرض لـ UNION ALL للجداول المختلفة.عند إضافة جدول، ستحتاج إلى إضافته إلى طريقة العرض، ولكن بخلاف ذلك سيبدو كجدول واحد.

CREATE VIEW modules AS (
    SELECT * FROM mod_A
    UNION ALL 
    SELECT * FROM mod_B
    UNION ALL 
    SELECT * FROM mod_C
);

select * from modules where section_id=value;
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top