SQL Conundrum ، كيفية تحديد أحدث تاريخ للجزء ، ولكن صف واحد فقط لكل جزء (فريد)

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

سؤال

أحاول لف رأسي حول هذا الصباح.

أحاول أن أظهر inventory حالة الأجزاء (لمنتجاتنا) ويصبح هذا الاستعلام معقدًا فقط إذا حاولت إعادة جميع الأجزاء.

اسمحوا لي أن أضعها:

  • جدول واحد inventoryReport
  • لدي قائمة مميزة من الأجزاء X التي أرغب في عرضها ، والتي يجب أن تكون نتيجة X # من الصفوف (صف واحد لكل جزء يوضح أحدث إدخال المخزون).
  • يتكون الجدول من إدخالات مؤرخة لتغييرات المخزون (لذلك أحتاج فقط إلى LATEST دخول التاريخ لكل جزء).
  • جميع البيانات الواردة في هذا الجدول المفرد ، لذلك لا يوجد أي صلة ضرورية.

حاليًا لجزء واحد ، يكون الأمر بسيطًا إلى حد ما ويمكنني إنجاز ذلك عن طريق القيام بـ SQL التالي (لإعطائك بعض الأفكار):

SELECT     TOP (1) ldDate, ptProdLine, inPart, inSite, inAbc, ptUm, inQtyOh + inQtyNonet AS in_qty_oh, inQtyAvail, inQtyNonet, ldCustConsignQty, inSuppConsignQty
FROM         inventoryReport
WHERE     (ldPart = 'ABC123')
ORDER BY ldDate DESC

هذا يجعلني أعلى صف واحد ، بسيط جدًا لكل جزء ، ومع ذلك أحتاج إلى إظهار كل X (دعنا نقول 30 جزءًا). لذلك أنا بحاجة إلى 30 صفًا ، مع هذه النتيجة. بالطبع ، سيكون الحل البسيط هو حلقة X# من مكالمات SQL في الكود الخاص بي (ولكن سيكون مكلفًا) وسيكون ذلك كافياً ، لكن لهذا الغرض ، أود أن أعمل هذا SQL أكثر لتقليل مكالمات X# مرة أخرى إلى DB (إذا لم يكن الحاجة) وصولاً إلى استفسار واحد فقط.

من ما يمكنني رؤيته هنا ، أحتاج إلى تتبع أحدث تاريخ لكل عنصر بطريقة أو بأخرى أثناء البحث عن مجموعة النتائج الخاصة بي.

سأفعل في النهاية

WHERE ldPart in ('ABC123', 'BFD21', 'AA123', etc)

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

أفكار؟ انا عالق...

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

المحلول

تعديل: تأكد من اختبار أداء كل حل. كما أشار في هذا السؤال, ، قد تتفوق طريقة CTE باستخدام ROW_Number.

;with cteMaxDate as (
    select ldPart, max(ldDate) as MaxDate
        from inventoryReport
        group by ldPart
)
SELECT md.MaxDate, ir.ptProdLine, ir.inPart, ir.inSite, ir.inAbc, ir.ptUm, ir.inQtyOh + ir.inQtyNonet AS in_qty_oh, ir.inQtyAvail, ir.inQtyNonet, ir.ldCustConsignQty, ir.inSuppConsignQty
    FROM cteMaxDate md
        INNER JOIN inventoryReport ir
            on md.ldPart = ir.ldPart
                and md.MaxDate = ir.ldDate

نصائح أخرى

  SELECT *
  FROM   (SELECT i.*,
      ROW_NUMBER() OVER(PARTITION BY ldPart ORDER BY ldDate DESC) r
      FROM   inventoryReport i
      WHERE  ldPart in ('ABC123', 'BFD21', 'AA123', etc)
         )
  WHERE  r = 1

تحتاج إلى الانضمام إلى مسابقة فرعية:

SELECT i.ldPart, x.LastDate, i.inAbc
FROM inventoryReport i
INNER JOIN (Select ldPart, Max(ldDate) As LastDate FROM inventoryReport GROUP BY ldPart) x
on i.ldPart = x.ldPart and i.ldDate = x.LastDate
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top