سؤال

لدي سؤال مثل هذا:

SELECT t1.id,
    (SELECT COUNT(t2.id)
     FROM t2
     WHERE t2.id = t1.id
          ) as num_things
FROM t1
WHERE num_things = 5;

الهدف هو الحصول على معرف جميع العناصر التي تظهر 5 مرات في الجدول الآخر.ولكن يمكنني الحصول على هذا الخطأ:

ERROR: column "num_things" does not exist
SQL state: 42703

أنا ربما تفعل شيئا سخيفا هنا ، أنا جديدة إلى حد ما إلى قواعد البيانات.هل هناك طريقة لإصلاح هذا الاستعلام حتى أستطيع الوصول num_things?أو إذا لم يكن هناك أي وسيلة أخرى لتحقيق هذه النتيجة ؟

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

المحلول

وأعتقد أنك يمكن أن مجرد كتابة الاستعلام الخاص بك مثل ذلك:

SELECT t1.id
FROM t1
WHERE (SELECT COUNT(t2.id)
     FROM t2
     WHERE t2.id = t1.id
          ) = 5;

نصائح أخرى

بعض النقاط الهامة حول استخدام SQL:

  • لا يمكنك استخدام عمود الأسماء المستعارة في جملة WHERE, ولكن يمكن في وجود الشرط.هذا هو سبب الخطأ لديك.
  • يمكنك القيام بعملك أفضل باستخدام الانضمام إلى المجموعة من خلال استخدام يرتبط الاستعلامات الفرعية.سيكون أسرع بكثير.
  • استخدام وجود بند تصفية المجموعات.

هذه هي الطريقة التي كنت أكتب هذا الاستعلام:

SELECT t1.id, COUNT(t2.id) AS num_things
FROM t1 JOIN t2 USING (id)
GROUP BY t1.id
HAVING num_things = 5;

أنا أدرك هذا الاستعلام يمكن تخطي JOIN مع t1 ، كما في تشارلز Bretana الحل.ولكن أفترض أنك قد تريد الاستعلام لتشمل بعض الأعمدة الأخرى من t1.


Re:السؤال في التعليق:

الفرق هو أن WHERE شرط يتم تقييم الصفوف قبل GROUP BY يقلل من المجموعات على صف واحد لكل مجموعة.على HAVING شرط تقييمها بعد أن يتم تشكيل مجموعات.لذا لا يمكنك ، على سبيل المثال ، تغيير COUNT() مجموعة باستخدام HAVING;يمكنك فقط استبعاد المجموعة نفسها.

SELECT t1.id, COUNT(t2.id) as num
FROM t1 JOIN t2 USING (id)
WHERE t2.attribute = <value>
GROUP BY t1.id
HAVING num > 5;

في الاستعلام ، WHERE مرشحات صفوف مطابقة شرط ، HAVING مرشحات المجموعات التي تضم خمسة على الأقل من العد.

النقطة التي تسبب معظم الناس الارتباك عندما لا يكون GROUP BY شرط لذلك يبدو مثل HAVING و WHERE قابلة للتبادل.

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

SELECT <expensive expressions>
FROM t1
HAVING primaryKey = 1234;

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

SELECT <expensive expressions>
FROM t1
WHERE primaryKey = 1234;

لذلك باختصار, الاستعلامات يتم تشغيلها بواسطة مشغل قاعدة بيانات وفقا سلسلة من الخطوات:

  1. توليد مجموعة من الصفوف من الجدول(ق) ، بما في ذلك أي الصفوف التي تنتجها JOIN.
  2. تقييم WHERE شروط ضد مجموعة من الصفوف ، تصفية الصفوف التي لا تتطابق.
  3. حساب التعبيرات في تحديد قائمة لكل في مجموعة الصفوف.
  4. تطبيق عمود الأسماء المستعارة (ملاحظة هذا هو خطوة منفصلة ، مما يعني أنك لا يمكن استخدام الأسماء المستعارة في التعبير في اختيار من القائمة).
  5. تتكثف المجموعات صف واحد لكل مجموعة ، وفقا GROUP BY البند.
  6. تقييم HAVING شروط ضد الجماعات تصفية الجماعات التي لا تتطابق.
  7. نوع النتيجة ، وفقا ORDER BY البند.
أن

جميع الاقتراحات الأخرى العمل، ولكن الإجابة عن السؤال الأساسي الخاص بك سيكون كافيا لكتابة

  SELECT id  From T2
  Group By Id
  Having Count(*) = 5

وأود أن أذكر أن في كيو لا توجد وسيلة لاستخدام العمود مستعارة في وجود الشرط.

وأي بمعنى.

وSELECT usr_id AS my_id من يضطر المستخدم my_id = 1

والعمل متعود.

والمثال الآخر الذي لن تعمل:

وsu.usr_id SELECT AS my_id، COUNT (*) AS فال من sys_user AS سو GROUP BY su.usr_id بصعوبات فال => 1

وسوف يكون هناك نفس الخطأ: لا يعرف العمود فال

وايم highliting هذا لبيل Karwin كتبت شيئا غير صحيح حقا لبوستجرس:

و"لا يمكنك استخدام الأسماء المستعارة العمود في جملة WHERE، ولكن يمكنك في جملة HAVING. هذا هو سبب الخطأ الذي حصلت عليه."

وهذه محاولة

SELECT t1.id,
    (SELECT COUNT(t2.id) as myCount
     FROM t2
     WHERE t2.id = t1.id and myCount=5
          ) as num_things
FROM t1
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top