2013-06-25 2 views
2

Я пытаюсь присвоить право fifo_cost в определенном порядке на основании разницы между fifo_in_date и order_date: в fifo_cost связанной с наименьшей разницей между order_date и fifo_date_in должны быть отнесены к этому порядку.MySQL, имеющий утверждение не возвращая никаких строк

Следующий фрагмент mysql не возвращает никакой записи. Я ожидаю, что он вернет эту запись с fifo_date_in ближе всего к order_date, но, очевидно, я что-то упустил.

drop table if exists tmp; 

create table tmp (
order_sequence int, 
order_number int, 
order_date date, 
fifo_date_in date, 
fifo_cost float); 

INSERT INTO tmp (order_sequence, order_number, order_date, fifo_date_in, fifo_cost) VALUES (5613, 561, '2013-01-02','2009-01-01',1.55); 
INSERT INTO tmp (order_sequence, order_number, order_date, fifo_date_in, fifo_cost) VALUES (5613, 561, '2013-01-02','2009-02-01',2.55); 
INSERT INTO tmp (order_sequence, order_number, order_date, fifo_date_in, fifo_cost) VALUES (5613, 561, '2013-01-02','2009-03-01',3.55); 
INSERT INTO tmp (order_sequence, order_number, order_date, fifo_date_in, fifo_cost) VALUES (5613, 561, '2013-01-02','2009-04-01',4.55); 
INSERT INTO tmp (order_sequence, order_number, order_date, fifo_date_in, fifo_cost) VALUES (5613, 561, '2013-01-02','2009-05-01',5.55); 

SELECT 
    order_sequence, order_number, order_date, fifo_date_in, fifo_cost, datediff(order_date,fifo_date_in) as ddiff 
FROM tmp 
GROUP BY order_sequence, order_number, order_date 
HAVING datediff(order_date,fifo_date_in) = min(datediff(order_date,fifo_date_in)) 
+0

Прежде всего, я думаю, что вам нужно включить fifo_date_in и fifo_cost в вашу группу по статье, поскольку они являются регулярными столбцы без каких-либо агрегатных функций. Во-вторых, если вы выполняете запрос без предложения предложения в конце, это дает какие-либо результаты? – JanR

ответ

3

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

SELECT t.order_sequence, t.order_number, t.order_date, t.fifo_date_in, t.fifo_cost 
    FROM tmp t 
    INNER JOIN (SELECT order_sequence, order_number, order_date 
        ,MIN(datediff(order_date,fifo_date_in)) as ddiff 
       FROM tmp 
       GROUP BY order_sequence, order_number, order_date 
      ) m 
     ON (m.order_sequence = t.order_sequence 
      AND m.order_number = t.order_number 
      AND m.order_date = t.order_date 
      AND datediff(t.order_date, t.fifo_date_in) = m.ddiff) 

Кроме того, вы, возможно, придется рассмотреть абсолютное значение, если ближе всего может означать, до или после.

Вот SQLFiddle

+0

Спасибо (особенно за ссылку SQLFIDDLE, очень полезно). Решение «min & join back» в mysql кажется популярным для этой проблемы. Можно ли получить тот же результат без подзапроса, используя HAVING? – user2105469

+0

На самом деле, вам придется поблагодарить @ChristianMark за скрипку (спасибо, Кристиан!). Я не знаю, как это сделать без какого-либо подзапроса. Клавиша «group by» идентифицирует ключ. Затем есть два элемента, связанных с ключом: 'fifo_date_in' и' fifo_cost'. Для каждого из них необходимо применить агрегированную функцию. Но какой агрегат применим к 'fifo_cost'? Мы не знаем, до тех пор, пока мы не определим мин на дату, следовательно, необходимо соединение или подзапрос. Я не могу думать о другом. – Glenn

+1

Np. Рад помочь. Спасибо за ваш ответ, хотя я просто применил его к схеме. = D @ user2105469, я думаю, что это невозможно сделать без подзапроса, вместо этого создайте 'VIEW'. –

0

Проблема с вашим запросом - это утверждение.

Что вы хотите сделать, это MIN(datediff(order_date,fifo_date_in)) as ddiff в списке, который найдет самое низкое значение разницы. Затем вы можете использовать group by для группировки результатов. Царапины мой комментарий до, ваш group by на самом деле правильно:

drop table if exists tmp; 

create table tmp (
order_sequence int, 
order_number int, 
order_date date, 
fifo_date_in date, 
fifo_cost float); 

INSERT INTO tmp (order_sequence, order_number, order_date, fifo_date_in, fifo_cost) VALUES (5613, 561, '2013-01-02','2009-01-01',1.55); 
INSERT INTO tmp (order_sequence, order_number, order_date, fifo_date_in, fifo_cost) VALUES (5613, 561, '2013-01-02','2009-02-01',2.55); 
INSERT INTO tmp (order_sequence, order_number, order_date, fifo_date_in, fifo_cost) VALUES (5613, 561, '2013-01-02','2009-03-01',3.55); 
INSERT INTO tmp (order_sequence, order_number, order_date, fifo_date_in, fifo_cost) VALUES (5613, 561, '2013-01-02','2009-04-01',4.55); 
INSERT INTO tmp (order_sequence, order_number, order_date, fifo_date_in, fifo_cost) VALUES (5613, 561, '2013-01-02','2009-05-01',5.55); 


SELECT 
    order_sequence, order_number, order_date, fifo_date_in, fifo_cost, MIN(datediff(order_date,fifo_date_in)) as ddiff 
FROM tmp 
GROUP BY order_sequence, order_number, order_date 
+0

Не выбрасывает ли минимальный «датифф», независимо от стоимости? – user2105469

+0

Да, это возвращает самый низкий элемент ddiff, он не учитывает какую-либо стоимость, вам нужна самая низкая стоимость? – JanR

+0

Я пытаюсь получить стоимость, связанную с последней версией fifo_date_in, то есть последней стоимостью файла. Значение fifo_date_in само по себе не так важно, оно является самым последним. – user2105469

0

Вы можете использовать ORDER BY и LIMIT, и опускаем GROUP BY:

SELECT 
    order_sequence, order_number, order_date, fifo_date_in, fifo_cost, datediff(order_date,fifo_date_in) as ddiff 
FROM tmp 
ORDER BY ddiff 
LIMIT 1 
+0

Не возвращает ли это одну запись, независимо от количества уникальных порядковых номеров? – user2105469

+0

@ user2105469 Да, данные образца только имели 1 номер заказа. Я добавлю еще один запрос для всех номеров заказов – Bohemian