سؤال

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

أريد في الأساس استرداد الخطوة الأخيرة لكل عنصر يتم إعطاؤه مرجع دفعة.لذلك إذا قمت بذلك

Select * from HistoryTable where BatchRef = @BatchRef

سيعيد جميع الخطوات لجميع العناصر الموجودة في الدفعة - على سبيل المثال

حالة المعرف BatchRef ItemCount
1       1       Batch001        100
1       2       Batch001        110
2       1       Batch001        60
2       2       Batch001        100

لكن ما أريده حقاً هو:

حالة المعرف BatchRef ItemCount
1       2       Batch001        110
2       2       Batch001        100

يحرر:Appologies - لا يبدو أن علامات TABLE تعمل مع Markdown - اتبعت المساعدة حرفيًا، ويبدو جيدًا في المعاينة

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

المحلول

من الصعب نوعًا ما أن تفهم تصميم طاولتك - أعتقد أنك أكلت المحددات الخاصة بك.

الطريقة الأساسية للتعامل مع ذلك هي التجميع حسب الحقول الثابتة، وتحديد الحد الأقصى (أو الحد الأدنى) لبعض القيم الفريدة (عادةً ما يعمل التاريخ والوقت بشكل جيد).في حالتك، أنا يفكر أن GROUP BY سيكون BatchRef وItemCount، وسيكون Id هو العمود الفريد الخاص بك.

ثم، انضم مرة أخرى إلى الجدول للحصول على كافة الأعمدة.شيء مثل:

SELECT * 
FROM HistoryTable
JOIN (
   SELECT 
       MAX(Id) as Id.
       BatchRef,
       ItemCount
   FROM HsitoryTable
   WHERE
       BacthRef = @batchRef
   GROUP BY
       BatchRef,
       ItemCount
 ) as Latest ON
   HistoryTable.Id = Latest.Id

نصائح أخرى

بافتراض أن لديك عمود هوية في الجدول ...

select 
    top 1 <fields> 
from 
    HistoryTable 
where 
    BatchRef = @BatchRef 
order by 
    <IdentityColumn> DESC

بافتراض أن معرفات العناصر مرقمة بشكل متزايد:

--Declare a temp table to hold the last step for each item id
DECLARE @LastStepForEach TABLE (
Id int,
Status int,
BatchRef char(10),
ItemCount int)

--Loop counter
DECLARE @count INT;
SET @count = 0;

--Loop through all of the items
WHILE (@count < (SELECT MAX(Id) FROM HistoryTable WHERE BatchRef = @BatchRef))
BEGIN
    SET @count = @count + 1;

    INSERT INTO @LastStepForEach (Id, Status, BatchRef, ItemCount)
        SELECT Id, Status, BatchRef, ItemCount
        FROM HistoryTable 
        WHERE BatchRef = @BatchRef
        AND Id = @count
        AND Status = 
        (
            SELECT MAX(Status) 
            FROM HistoryTable 
            WHERE BatchRef = @BatchRef 
            AND Id = @count
        )

END

SELECT * 
FROM @LastStepForEach
SELECT id, status, BatchRef, MAX(itemcount) AS maxItemcount 
FROM HistoryTable GROUP BY id, status, BatchRef 
HAVING status > 1 

من الصعب بعض الشيء فك تشفير بياناتك بالطريقة التي قامت بتنسيقها WMD، ولكن يمكنك استخدام نوع الخدعة التي تحتاجها باستخدام تعبيرات الجدول الشائعة في SQL 2005:

with LastBatches as (
    select Batch, max(Id)
    from HistoryTable
    group by Batch
)
select *
from HistoryTable h
    join LastBatches b on b.Batch = h.Batch and b.Id = h.Id

أو استعلام فرعي (بافتراض أن المجموعة تعمل في الاستعلام الفرعي - لا أتذكر الجزء العلوي من رأسي):

select *
from HistoryTable h
    join (
        select Batch, max(Id)
        from HistoryTable
        group by Batch
    ) b on b.Batch = h.Batch and b.Id = h.Id

يحرر:كنت أفترض أنك تريد العنصر الأخير كل حزمة.إذا كنت في حاجة إليها فقط لدفعة واحدة، فإن الإجابات الأخرى (القيام بالأعلى 1 والترتيب التنازلي) هي الطريقة الصحيحة.

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

SELECT TOP 1 ...

إذا كنت تستخدم MSSQL 2k أو إصدارًا أقدم، أو الإصدار المتوافق مع SQL

SELECT * FROM (
  SELECT
    ROW_NUMBER() OVER (ORDER BY key ASC) AS rownumber,
    columns
  FROM tablename
) AS foo
WHERE rownumber = n

لأي إصدار آخر (أو لأنظمة قواعد البيانات الأخرى التي تدعم التدوين القياسي)، أو

SELECT ... LIMIT 1 OFFSET 0

لبعض المتغيرات الأخرى دون دعم SQL القياسي.

أنظر أيضا هذا سؤال لبعض المناقشات الإضافية حول اختيار الصفوف.قد يكون استخدام الدالة التجميعية max() أسرع أو لا يكون اعتمادًا على ما إذا كان حساب القيمة يتطلب فحصًا للجدول.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top