2013-04-10 5 views
0

я получил в таблице «EMPRESAS»Сравните различия между первой и второй строкой для группы

dbo.empresas 

    id | name | delegacion_id 
    ------------------------- 
    1 | A |  3 
    2 | B |  3 
    3 | C |  3 
    4 | D |  4 

с «Pagos» столом

dbo.pagos 


    id | id_empresa | monto | periodo 
    ---------------------------------- 
    1 | 1  | 120 | 2012-11-01 
    2 | 1  | 125 | 2012-12-01 
    3 | 2  | 150 | 2012-11-01 
    4 | 1  | 200 | 2013-01-01 
    5 | 2  | 151 | 2012-12-01 

У меня есть значение X, который представляет собой процент.

Мне нужно, чтобы показать «EMPRESAS», что, сравнивая «МОНТОС» их двух последних «Pagos» (по заказу Periodo), изменились по крайней мере + X% или -Х% от especific id_delegacion

Например, если мы выполним этот запрос с этими примерами значений, учитывая

X = 10 id_delegacion = 3

выход ожидается будет:

name | periodo | monto 
--------------------------- 
A | 2012-12-01 | 125 
A | 2013-01-01 | 200 

empresa A - from delegacion_id = 3, а сравнение между двумя последними pagos, упорядоченное по периоду desc (200 => 125), превышает 10%.

B не показан, потому что сравнение меньше 10%.

С не показали, потому что не имеет строки в таблице «Pagos»

D из другой делегации.

Как я могу получить этот желаемый результат? Для записи используется MySQL 5.5.8.

Что я сделал

Я получил это

select P.id_empresa, max(periodo) as periodo from 
     pagos P 
     where id_empresa in(
           select e.id 
           from empresa E 
           where E.id_delegacion = 3 
          ) 
     group by p.id_empresa, p.periodo 
     having count(*) > 1 

с этим я получил "EMPRESAS", которые имеют более чем одну строку "Паго", и получил id_delegation = 3. Также получите первый период (максимум), но я не знаю, как получить второй для каждой empresa и сравнить их.

благодаря

ответ

1

Это мой запрос:

SELECT 
    empresas.name, 
    pagos.periodo, 
    pagos.monto 
FROM 
    pagos INNER JOIN (
    SELECT 
     lst.id id1, 
     prc.id id2 
    FROM (
     SELECT 
     p1.id_empresa, 
     MAX(p1.periodo) last_p, 
     MAX(p2.periodo) prec_p 
     FROM 
     pagos p1 INNER JOIN pagos p2 
     ON p1.id_empresa = p2.id_empresa 
      AND p2.periodo < p1.periodo 
     GROUP BY 
     id_empresa) latest 
     INNER JOIN 
     pagos lst ON lst.id_empresa = latest.id_empresa AND lst.periodo=latest.last_p 
     INNER JOIN 
     pagos prc ON prc.id_empresa = latest.id_empresa AND prc.periodo=latest.prec_p 
    WHERE 
     lst.monto > prc.monto * 1.1) ids 
    ON pagos.id IN (ids.id1, ids.id2) 
    INNER JOIN 
    empresas 
    ON pagos.id_empresa = empresas.id 
WHERE 
    delegacion_id=3 

Я думаю, что это может быть упрощена, если вы хотите иметь значения на той же строке, например,

name | ultimo_periodo | ultimo_monto | anterior_periodo | anterior_monto 

См. Скрипку here.

Мне все еще интересно, можно ли его немного упростить, но я не уверен, что это так. Вот еще одно решение:

SELECT 
    empresas.name, 
    pagos.periodo, 
    pagos.monto 
FROM 
    pagos INNER JOIN empresas 
    ON pagos.id_empresa = empresas.id 
    INNER JOIN (
SELECT 
    id_empresa, 
    MAX(CASE WHEN row=1 THEN monto END) lst_monto, 
    MAX(CASE WHEN row=2 THEN monto END) prc_monto, 
    MAX(id) id1, MIN(id) id2 
FROM (

    SELECT 
    p1.*, COUNT(*) row 
    FROM 
    pagos p1 INNER JOIN pagos p2 
    ON p1.id_empresa = p2.id_empresa 
     AND p1.periodo <= p2.periodo 
    INNER JOIN empresas 
    ON p1.id_empresa = empresas.id 
    WHERE 
    empresas.delegacion_id = 3 
    GROUP BY 
    p1.id, p1.id_empresa, p1.monto, p1.periodo 
    HAVING 
    COUNT(*)<=2 
    ORDER BY 
    p1.id_empresa, p1.periodo desc 
) s 
GROUP BY 
    id_empresa 
HAVING 
    lst_monto>prc_monto*1.1 
) l ON pagos.id IN (l.id1, l.id2) 

Пожалуйста, смотрите скрипку here.

+0

выглядит хорошо, но мне нужно идти. Завтра я проверю это! спасибо –

+0

ничего себе, это действительно хорошо. Это сработает, но теперь, когда вы говорите, альтернатива (показать в том же ряду) тоже может быть. Как будет в этом случае? –

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