صعب استعلام SQL:الوسم شعبية نماذج معقدة الجمعيات

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

  •  05-07-2019
  •  | 
  •  

سؤال

أنا لست حتى متأكدا من هذا من الممكن القيام به بكفاءة ، ولكن هنا مشكلتي:

أنا أكتب ما هو في الأساس محرك بلوق حيث بلوق وظيفة و كل الردود على كل بلوق وظيفة يمكن أن يوصف.

لذا أنا يمكن أن يكون لها بلوق وظيفة معلم "المكدس" ، ردا على هذا المنصب الموسومة "تجاوز".

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

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

وهنا وصف الجداول/المجالات التي قد تكون ذات صلة:

BlogPosts
| id     # Primary key for all tables, Rails-style

BlogComments
| id
| blog_post_id

Tags
| id
| name   # 'foo'

Taggings
| id
| tag_id
| blog_post_id
| blog_comment_id

هناك بعض denormalization في Taggings أجل الراحة.إذا كان شخص ما العلامات BlogPost ، يملأ في blog_post_id المجال ، blog_comment_id يظل باطلا.إذا كان شخص ما العلامات تعليق على مشاركة, يملأ في كل blog_post_id و blog_comment_id.

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

وذلك بفضل!

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

المحلول

حتى الآن لا أرى أي شيء معقد في الطلب الخاص بك:

SELECT
  tag_id,
  COUNT(blog_post_id) + COUNT(blog_comment_id) tag_count
FROM
  Taggings
GROUP BY
  tag_id
ORDER BY
  COUNT(blog_post_id) + COUNT(blog_comment_id) DESC

إذا كنت ترغب في الاعتماد المتضررة "التدوينات" فقط, أعتقد أن هذه هي الطريقة:

SELECT
  t.id    tag_id,
  t.name  tag_name,
  COUNT(DISTINCT COALESCE(x.blog_post_id, c.blog_post_id)) tag_count
FROM
  Tags                    t  
  INNER JOIN Taggings     x ON x.tag_id = t.id
  LEFT  JOIN BlogComments c ON c.id     = x.blog_comment_id
GROUP BY
  t.id,
  t.name
ORDER BY
  COUNT(DISTINCT COALESCE(x.blog_post_id, c.blog_post_id)) DESC

نصائح أخرى

ربما أنا في عداد المفقودين شيء واضح ولكن لأن لديك "اذا كان هناك فئة تعليق على مشاركة, يملأ في كل blog_post_id و blog_comment_id", sql التالية ينبغي أن تفعل خدعة. أفترض هنا أن الكلمات.اسم هنا سوف تكون فريدة من نوعها.

SELECT MIN(ts.tag_id), t.name, COUNT(ts.blog_post_id) as rank
FROM Taggings ts
    INNER JOIN Tags t ON ts.tag_id = t.id
GROUP BY t.name
ORDER BY COUNT(ts.blog_post_id) DESC

اتمنى ان يكون ما تبحث عنه.

لم حاولت ولكن ماذا عن شيء مثل هذا؟:

select t.Id, 
    t.Name, 
    count(*)

from Taggings tings
inner join Tags t
    on (t.id = tings.blog_post_id or t.id = tings.blog_comment_id)

group by t.Id, t.Name
order by count(*) desc
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top