У меня есть один вопрос по sql, может кто мне поможет. В этом случае у меня есть одна таблица, в которой записи выглядят так:
Name Account Percent MonthValue DateFrom
Element1 500 15 500 2016-01-01
Element1 501 45 500 2016-01-01
Element1 502 40 500 2016-01-01
Element1 500 100 500 2017-01-01
Element2 503 80 3000 2016-01-01
Element2 504 20 3000 2016-01-01
Element2 505 45 3000 2017-06-01
Element2 503 55 3000 2017-06-01
Я должен показать результат, где каждый месяц я могу видеть, у какого элемента процент от счета. Например, Element1 в феврале 2016 года на счете 501 имеет 45 процентов от значения 1000 на самом деле 450. У меня проблема с отображением значения, когда один и тот же элемент имеет несколько дат. Например, в декабре 2016 года у Element1 было 3 аккаунта, но в январе 2017 года у Element1 было 1 аккаунт. У меня есть свидания, на которые я должен рассчитывать, но у меня нет свиданий, на которые я должен рассчитывать. Результат, которого я ожидаю, будет таким:
Хочу узнать, какой аккаунт и какой процент от этих аккаунтов в декабре 2016 года, получаю результат:
Name Account Percent Value
Element1 500 15 75
Element1 501 45 225
Element1 502 40 200
Element2 503 80 2400
Element2 504 20 600
В противном случае я хочу знать, какой аккаунт и какой процент от этих аккаунтов находится в июне 2017 года, и тогда я получаю результат:
Name Account Percent Value
Element1 500 100 500
Element2 505 45 1350
Element2 503 55 1650
Надеюсь, что объясню суть проблемы. Ниже я показываю свой sql в текущей форме:
SELECT
a.NAME,
a.ACCOUNT,
a.PERCENT,
a.MONTHVALUE,
a.DATEFROM
from ELEMENTS a
where a.DATEFROM between :DATE_FROM and :DATE_TO
где: DATE_FROM,: DATE_TO - параметры для сравнения дат (но у меня нет столбца для сравнения: DATE_TO). Пожалуйста, помогите мне с этой проблемой, я надеюсь, что кто-то знает решение, отличное от вставки в столбец таблицы, у которого есть дата до.
Да конечно, ошибка моя :)
Примеры с «Я получаю результат» показывают результат ожидал или фактический результат?
Следующий запрос выводит желаемый результат на основе ваших примеров:
declare @querydate date;
set @querydate = '2016-02-01'; --Set the desired query date
SELECT a.Name, a.Account, a.[Percent],
a.MonthValue * a.[Percent] / 100 as Value,
a.DateFrom
FROM ELEMENTS a
JOIN
(SELECT Name, MAX(DateFrom) as LastElementDate
FROM ELEMENTS
WHERE DateFrom <= @querydate
GROUP BY Name) b
ON a.Name = b.Name
AND a.DateFrom = b.LastElementDate
Идея состоит в том, чтобы создать подзапрос (таблица b), содержащий последнюю записанную дату для каждого элемента. (MAX (DateFrom). Кроме того, @querydate используется для фильтрации нежелательных строк, в которых дата превышает желаемую дату. Затем эта таблица присоединяется к основной таблице на основе Name и LastElementDate, таким образом извлекаются только те записи, дата которых совпадает с последней действительной датой.
Этот вопрос касается Firebird, похоже, вы используете синтаксис Microsoft SQL Server.
Вы правы, моя беда, метку Firebird я не заметил. Возможно, есть способ адаптировать его, но я пока не могу его протестировать
Помимо использования declare
и set
и маркера параметра @
и использования квадратных скобок вместо двойных кавычек, я думаю, это сработает (возможно, 100
необходимо заменить на 100.0
, чтобы обеспечить значение двойной точности).
Итак, в основном, строка действительна до тех пор, пока новая строка (строки) с тем же элементом, но с более поздней датой не заменит ее? Кроме того, почему вы утверждаете, что Element1 - счет 501 имеет 45% от 1000? Разве это не должно быть 45% от 500?