2013-09-14 2 views
4

Я работаю с mysql, и я никогда не сталкивался с такой большой проблемой. Я надеюсь, что вы можете помочь ..Выберите запись, только если она имеет более низкое значение.

У меня есть 1 стол называемые отчеты:

ID   SerialNumber   Remain_Toner_Black 
7099  Z5UEBJAC900002Y  37 
7281  Z5UEBJAC900002Y  36 
7331  Z5UEBJAC900002Y  100 
7627  8Z37B1DQ100105N  58 
7660  8Z37B1DQ100105N  57 
5996  CND8DDM2FH   83 
5971  CND8DDM2FH   83 
7062  3960125290   0 
7088  3960125290   93 
7100  3960125290   100 

Теперь я хочу, чтобы иметь возможность выбора записей из таблицы, где Remain_Toner_Black выше, чем Remain_Toner_Black предыдущего ряда в таблица с тем же SerialNumber (по предыдущему я имею в виду более низкий идентификатор с тем же SerialNumber).

Для вышеуказанных записей я хочу результаты ниже:

ID   SerialNumber  Remain_Toner_Black_Before Remain_Toner_Black_After 
7331  Z5UEBJAC900002Y  36       100 
7088  3960125290   0       93 
7100  3960125290   93       100 
+0

'@Guy Messika' показать, что вы пробовали до сих пор ... – Vijay

+0

Я имею в виду, у меня есть 2 ряда с таким же SerialNumber .. один с ID: 7331 И один с ID: 7281. ну предыдущий это строка с идентификатором: 7281. Даже если строка с идентификатором типа 7330 существует, но имеет другой SerialNumber, это не считается предыдущим –

ответ

4
SELECT a.ID, a.SerialNumber, 
     b.Remain_Toner_Black BeforeCount, 
     a.Remain_Toner_Black AfterCount 
FROM  
     (
      SELECT A.ID, 
        A.SerialNumber, 
        A.Remain_Toner_Black, 
        (
         SELECT COUNT(*) 
         FROM tableName c 
         WHERE c.SerialNumber = a.SerialNumber AND 
           c.ID <= a.ID) AS RowNumber 
      FROM TableName a 
     ) a 
     INNER JOIN 
     (
      SELECT A.ID, 
        A.SerialNumber, 
        A.Remain_Toner_Black, 
        (
         SELECT COUNT(*) 
         FROM tableName c 
         WHERE c.SerialNumber = a.SerialNumber AND 
           c.ID <= a.ID) AS RowNumber 
      FROM TableName a 
     ) b ON a.SerialNumber = b.SerialNumber AND 
       a.RowNumber = b.RowNumber + 1 
WHERE b.Remain_Toner_Black < a.Remain_Toner_Black 

ВЫХОДА

╔══════╦═════════════════╦═════════════╦════════════╗ 
║ ID ║ SERIALNUMBER ║ BEFORECOUNT ║ AFTERCOUNT ║ 
╠══════╬═════════════════╬═════════════╬════════════╣ 
║ 7331 ║ Z5UEBJAC900002Y ║   36 ║  100 ║ 
║ 7088 ║ 3960125290  ║   0 ║   93 ║ 
║ 7100 ║ 3960125290  ║   93 ║  100 ║ 
╚══════╩═════════════════╩═════════════╩════════════╝ 

КРАТКОЕ ОПИСАНИЕ

То, что запрос выше, делает это генерирует порядковый номер, который имитирует ROW_NUMBER() на другом RDBS для каждого SerialNumber заказанного ID в порядке возрастания.

Затем два подзапроса соединяются через SerialNumber и генерируют последовательный номер. По сгенерированному номеру значение в первом подзапросе должно быть равно плюс одно из значения во втором подзапросе, чтобы получить количество тонера на следующем уровне.

+0

! спасибо –

1

MySQL (или, действительно, большинство других СУБД) не позволяет легко сравнивать между рядами.

Для выполнения такого запроса вы должны либо выполнить очень дорогое объединение, сравнивая одну версию таблицы с несколькими строками другой версии таблицы, либо построить сложное выражение с использованием пользовательских переменных.

Например (с пользовательскими переменными):

SELECT ID, SerialNumber, @x Remain_Toner_Before, 
     @x := Remain_Toner_Black AS Remain_Toner_After 
FROM Reports, (SELECT @x := -4) x 
WHERE Remain_Toner_Black > @x 
    AND SerialNumber = '3960125290' 
ORDER BY ID; 

(-4 от вашего комментария к другой ответ)

Лучшее решение сделать это с помощью курсоров или в коде приложения, где вам нужно сделать только один проход и сравнить простую логику с помощью переменных в коде курсора или приложения.

+0

в других rdbms, есть функции, которые могут помочь вам сравнить ряд за строкой, например. 'LAG и LEAD'. –

+0

Спасибо, отредактирован в соответствии. –

+0

Я попытался ответить выше, и он возвращает 1398 строк вместо 4. –

Смежные вопросы