ضم أحدث علامات بيانات تعريف المستخدم المختلفة إلى صفوف المستخدم

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

  •  09-06-2019
  •  | 
  •  

سؤال

لدي قاعدة بيانات postgres تحتوي على جدول مستخدم (معرف المستخدم، الاسم الأول، اسم العائلة) وجدول بيانات تعريف المستخدم (معرف المستخدم، الكود، المحتوى، تاريخ الإنشاء).أقوم بتخزين معلومات مختلفة حول كل مستخدم في جدول بيانات تعريف المستخدم حسب الكود والاحتفاظ بسجل كامل.على سبيل المثال، يمتلك المستخدم (userid 15) البيانات التعريفية التالية:

15, 'QHS', '20', '2008-08-24 13:36:33.465567-04'  
15, 'QHE', '8', '2008-08-24 12:07:08.660519-04'  
15, 'QHS', '21', '2008-08-24 09:44:44.39354-04'  
15, 'QHE', '10', '2008-08-24 08:47:57.672058-04'  

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

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

المحلول

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

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

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

من الشائع أن هناك طريقة واحدة لتحديد مجموعة الحقول الحالية.ما عليك سوى تحديد جميع الإدخالات التي تحتوي على المستخدم النشط و"تاريخ الإهمال" أو "صالح" أو "نشط" حقيقي.

قد تكون مهتمًا بإلقاء نظرة على إدخال ويكيبيديا قواعد البيانات المؤقتة والمقالة مسرد إجماعي لمفاهيم قاعدة البيانات المؤقتة.

نصائح أخرى

هذا في الواقع ليس بالأمر الصعب في PostgreSQL لأنه يحتوي على "متميز" جملة في بناء جملة SELECT الخاص بها (DISTINCT ON ليس SQL قياسيًا).

SELECT DISTINCT ON (code) code, content, createtime
FROM metatable
WHERE userid = 15
ORDER BY code, createtime DESC;

سيؤدي ذلك إلى قصر النتائج التي يتم إرجاعها على النتيجة الأولى لكل رمز فريد، وإذا قمت بفرز النتائج حسب وقت الإنشاء تنازليًا، فستحصل على الأحدث من كل منها.

التحديد الفرعي هو الطريقة القياسية للقيام بهذا النوع من الأشياء.تحتاج فقط إلى قيد فريد على معرف المستخدم والرمز والتاريخ - وبعد ذلك يمكنك تشغيل ما يلي:

SELECT * 
FROM Table
JOIN (
   SELECT UserId, Code, MAX(Date) as LastDate
   FROM Table
   GROUP BY UserId, Code
) as Latest ON
   Table.UserId = Latest.UserId
   AND Table.Code = Latest.Code
   AND Table.Date = Latest.Date
WHERE
   UserId = @userId
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top