سؤال

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

وأنا أكتب استعلام بحث لإرجاع قائمة الوثائق (التي تمت تصفيتها وفقا لمعايير مختلفة) مع أحدث هوية المستخدم للوصول عادت كل وثيقة في مجموعة النتائج.

وهكذا ل


    DOCUMENTS
    ID | NAME
    1  | Document 1
    2  | Document 2
    3  | Document 3
    4  | Document 4
    5  | Document 5

    HISTORY
    DOC_ID | USER_ID | TIMESTAMP
    1      | 12345   | TODAY
    1      | 11111   | IN THE PAST
    1      | 11111   | IN THE PAST
    1      | 12345   | IN THE PAST
    2      | 11111   | TODAY
    2      | 12345   | IN THE PAST
    3      | 12345   | IN THE PAST

ويهمني أن تبحث للحصول على عائد من بحثي مثل


    ID | NAME       | LAST_USER_ID
    1  | Document 1 | 12345
    2  | Document 2 | 11111
    3  | Document 3 | 12345
    4  | Document 4 | 
    5  | Document 5 | 

هل يمكنني بسهولة القيام بذلك مع الاستعلام SQL واحدة وصلة بين الجدولين؟

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

المحلول

ومراجعة ما ينتج أندي وايت، واستبدال الأقواس المربعة (MS SQL خادم التدوين) مع DB2 (وSQL القياسية ISO) "معرفات محدد":

SELECT d.id, d.name, h.last_user_id
    FROM Documents d LEFT JOIN
         (SELECT r.doc_id AS id, user_id AS last_user_id
              FROM History r JOIN
                   (SELECT doc_id, MAX("timestamp") AS "timestamp"
                        FROM History
                        GROUP BY doc_id
                   ) AS l
                   ON  r."timestamp" = l."timestamp"
                   AND r.doc_id      = l.doc_id
         ) AS h
         ON d.id = h.id

ولست متأكدا تماما ما إذا كانت "الطابع الزمني" أو "الطابع الزمني" هو الصحيح - ربما هذا الأخير

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

نصائح أخرى

وأنا لا يمكن أن تحصل على "بصعوبات MAX (الطابع الزمني)" لتشغيل في SQL Server - أعتقد وجود يتطلب التعبير المنطقية مثل "وجود حد أقصى (الطابع الزمني)> 2009-03-05" أو شيء من هذا، والذي لا تطبق في هذه الحالة. (I يمكن أن نفعل شيئا خطأ ...)

وهنا هو الشيء الذي يبدو للعمل - لاحظ الانضمام لديها 2 شروط (لست متأكدا إذا كان هذا هو جيد أم لا):

select
    d.ID,
    d.NAME,
    h."USER_ID" as "LAST_USER_ID"
from Documents d
left join History h
    on d.ID = h.DOC_ID
    and h."TIMESTAMP" =
    (
        select max("TIMESTAMP")
        from "HISTORY"
        where "DOC_ID" = d.ID
    )

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

select a.ID, a.NAME,
(select x.user_id
 from HISTORY x
 where x.doc_id = a.id
   and x.timestamp = (select max(x1.timestamp)
                      from HISTORY x1
                      where x1.doc_id = x.doc_id)) as LAST_USER_ID
from DOCUMENTS a
where <your criteria here>

وأعتقد أنه يجب أن يكون شيئا من هذا القبيل:

SELECT ID, Name,  b.USER_ID as LAST_USER_ID
FROM DOCUMENTS a LEFT JOIN
    ( SELECT DOC_ID, USER_ID 
          FROM HISTORY
              GROUP BY DOC_ID, USER_ID
              HAVING MAX( TIMESTAMP )) as b
    ON a.ID = b.DOC_ID

وهذا قد عمل أيضا:

SELECT ID, Name,  b.USER_ID as LAST_USER_ID
FROM DOCUMENTS a 
  LEFT JOIN HISTORY b ON a.ID = b.DOC_ID
GROUP BY DOC_ID, USER_ID
HAVING MAX( TIMESTAMP )
Select ID, Name, User_ID
From Documents Left Outer Join
History a on ID = DOC_ID
Where ( TimeStamp = ( Select Max(TimeStamp)
                      From History b
                      Where a.DOC_ID = b.DOC_ID ) OR
        TimeStamp Is NULL )  /* this accomodates the Left */
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top