#sql #powerbuilder #sqlanywhere
#sql #powerbuilder #sqlanywhere
Вопрос:
У меня есть таблица, содержащая pipes
которые установлены в определенном месте. Установленные даты всегда заполняются, удаленные даты могут быть нулевыми
Type Installed Removed Length
PT2 01/01/2011 NULL 2000
PT2 01/01/2011 NULL 2000
PT1 01/01/2011 NULL 1200
PT1 01/01/2011 NULL 1200
PT1 15/02/2011 25/02/2011 1000
PT1 15/02/2011 25/02/2011 1000
Теперь мне нужен обзор общей длины для каждого типа, который был установлен за данный месяц, поэтому результат должен быть, например, от 01/02/2011
до 28/02/2011
:
Type From To Length
PT2 01/02/2011 28/02/2011 4000
PT1 01/02/2011 14/02/2011 2400
PT1 15/02/2011 24/02/2011 4400 Edit: (starts on 15 not 14)
PT1 25/02/2011 28/02/2011 2400
РЕДАКТИРОВАТЬ: Разъяснение по этому ожидаемому результату.
В конце это будет использовано для просмотра общей длины канала в любой данный момент в течение запрошенного месяца. Итак, если вы посмотрите на таблицу выше, в течение 2 февраля были установлены PT2
каналы. Они были установлены в январе, но все еще присутствуют, поэтому в течение всего месяца общая длина составляет 4000.
То же самое для PT1
: С начала февраля установлено 2 канала PT1, то есть 2400. Однако 15-го числа устанавливаются дополнительные 2 канала PT1 длиной 1000, так что с 15-го по 25-е общая длина каналов PT1 составляет 4400.
Эти 2 канала удаляются 25-го, так что с 25 по конец месяца снова 2400.
Я надеюсь, что теперь это имеет немного больше смысла.
Я пытаюсь понять, как это сделать в SQL, это для отчета, и обычно в любой данный месяц устанавливаются сотни таких каналов.
Это для использования в приложении Powerbuilder, поэтому, если вы знаете какую-либо хитрость datawindow, которая может помочь, не стесняйтесь поделиться.
Комментарии:
1. Вы имеете в виду, что в феврале (ваши даты приведены в формате DDMMYYY) длина для PT1 должна быть отрицательным числом, так что, если бы вы запускали отчет за первый квартал года, 2000 футов, удаленные в феврале, были бы вычтены из 2400 футов PT1, установленных в январе, для чистой установленной длины в 400 футов для PT1 за квартал?
2. Извините, что не могу удалить это — StackOverflow не дает вам много времени на обдумывание при вводе текста или времени на то, чтобы быть прерванным телефонным звонком, прежде чем он закроет возможность изменять / удалять комментарии.
Ответ №1:
Слишком много удовольствия от этого! Я позволил себе несколько вольностей, например, предположил порядок сортировки и изменил критерии вашего запроса на диапазон дат вместо объявления месяца.
Для начала я изменил набор данных с диапазонов дат на даты изменений и количество изменений (положительные значения на дату установки, отрицательные значения на дату удаления).
SELECT type,
installed as date_of_change,
length change_of_length
FROM pipes
WHERE (installed BETWEEN :date_start AND
:date_end) OR
((installed < :date_start) AND
(isnull (removed, :date_end) >= :date_start))
UNION ALL
SELECT type,
isnull (removed, dateadd (day, 1, :date_end)),
(length * -1)
FROM pipes
WHERE (installed BETWEEN :date_start AND
:date_end) OR
((installed < :date_start) AND
(isnull (removed, :date_end) >= :date_start))
ORDER BY type,
date_of_change
И, да, эти двоеточия перед аргументами (я переключил вас на даты начала и окончания… для меня проще, и теперь вы можете создавать отчеты за шесть месяцев) означает, что я использую DataWindow. (Держу пари, кто-нибудь может создать чисто SQL-подход с вышеупомянутым изменением концепции, но я придерживаюсь того, что знаю.)
Загрузите SQL в DataWindow (я использовал произвольную форму) и, при необходимости, установите сортировку на стороне клиента по типу и date_of_change (ремень и подтяжки). Набор данных включает в себя нулевые удаленные даты в качестве изменения на следующий день после окончания диапазона вашего запроса, поэтому создайте фильтр для исключения этих нулей:
date_of_change <= date_end
Создайте группу на основе типа и поместите тип в заголовок группы.
В группе сведений (куда отправляются все последующие элементы управления) создайте вычисление с именем date_from со следующим выражением:
if (date_of_change < date_start, date_start, date_of_change)
Создайте вычисление с именем date_to со следующим выражением:
if (type = type[1] and getrow() < rowcount() and date_of_change[1] <= date_end,
RelativeDate(date_of_change[1], -1), date_end )
Создайте вычисление с именем installed_length со следующим выражением:
cumulativesum ( change_of_length FOR GROUP 1)
Выберите все элементы управления в вашей группе сведений и придайте им видимое выражение:
if (date_of_change = date_of_change [1] and type = type[1], 0, 1)
что сделает их невидимыми, если следующая строка имеет тот же date_of_change и тип; вы хотите, чтобы отображалась только последняя строка с суммой всех сегодняшних действий.
Перетащите полосу сведений на нулевую высоту и автоматически измените высоту полосы сведений.
Это даст вам версию того, что вам нужно. Черт возьми, я пытался выполнить сортировку отчета по дате (не ясно, это то, что вы хотели, или сначала отсортировать по типу), но это нарушает функциональность CumulativeSum (). Может быть, кто-то другой сможет это выяснить.
Удачи,
Терри.
P.S. Если ЭТО ТАК, позвольте мне добавить вот это, вот экспорт моего прототипа. Это может быть вам полезно, а может и не быть.
release 11.5;
datawindow(units=0 timer_interval=0 color=1073741824 brushmode=0 transparency=0 gradient.angle=0 gradient.color=8421504 gradient.focus=0 gradient.repetition.count=0 gradient.repetition.length=100 gradient.repetition.mode=0 gradient.scale=100 gradient.spread=100 gradient.transparency=0 picture.blur=0 picture.clip.bottom=0 picture.clip.left=0 picture.clip.right=0 picture.clip.top=0 picture.mode=0 picture.scale.x=100 picture.scale.y=100 picture.transparency=0 processing=0 HTMLDW=no print.printername="" print.documentname="" print.orientation = 0 print.margin.left = 110 print.margin.right = 110 print.margin.top = 96 print.margin.bottom = 96 print.paper.source = 0 print.paper.size = 0 print.canusedefaultprinter=yes print.prompt=no print.buttons=no print.preview.buttons=no print.cliptext=no print.overrideprintjob=no print.collate=yes print.background=no print.preview.background=no print.preview.outline=yes hidegrayline=no showbackcoloronxp=no picture.file="" )
header(height=72 color="536870912" transparency="0" gradient.color="8421504" gradient.transparency="0" gradient.angle="0" brushmode="0" gradient.repetition.mode="0" gradient.repetition.count="0" gradient.repetition.length="100" gradient.focus="0" gradient.scale="100" gradient.spread="100" )
summary(height=0 color="536870912" transparency="0" gradient.color="8421504" gradient.transparency="0" gradient.angle="0" brushmode="0" gradient.repetition.mode="0" gradient.repetition.count="0" gradient.repetition.length="100" gradient.focus="0" gradient.scale="100" gradient.spread="100" )
footer(height=0 color="536870912" transparency="0" gradient.color="8421504" gradient.transparency="0" gradient.angle="0" brushmode="0" gradient.repetition.mode="0" gradient.repetition.count="0" gradient.repetition.length="100" gradient.focus="0" gradient.scale="100" gradient.spread="100" )
detail(height=0 color="536870912" transparency="0" gradient.color="8421504" gradient.transparency="0" gradient.angle="0" brushmode="0" gradient.repetition.mode="0" gradient.repetition.count="0" gradient.repetition.length="100" gradient.focus="0" gradient.scale="100" gradient.spread="100" height.autosize=yes )
table(column=(type=char(4) updatewhereclause=yes name=type dbname="pipes.type" )
column=(type=datetime updatewhereclause=yes name=date_of_change dbname="pipes.date_of_change" )
column=(type=long updatewhereclause=yes name=change_of_length dbname="pipes.change_of_length" )
retrieve="SELECT type, installed as date_of_change, length change_of_length
from pipes
where (installed BETWEEN :date_start AND :date_end) OR
((installed < :date_start) AND (isnull (removed, :date_end) >= :date_start))
union all
select type, isnull (removed, dateadd (day, 1, :date_end)), (length * -1)
from pipes
where (installed BETWEEN :date_start AND :date_end) OR
((installed < :date_start) AND (isnull (removed, :date_end) >= :date_start))
order by date_of_change, type" filter=" date_of_change <= date_end "arguments=(("date_start", date),("date_end", date)) sort="type A date_of_change A " )
group(level=1 header.height=76 trailer.height=0 by=("type" ) header.color="536870912" header.transparency="0" header.gradient.color="8421504" header.gradient.transparency="0" header.gradient.angle="0" header.brushmode="0" header.gradient.repetition.mode="0" header.gradient.repetition.count="0" header.gradient.repetition.length="100" header.gradient.focus="0" header.gradient.scale="100" header.gradient.spread="100" trailer.color="536870912" trailer.transparency="0" trailer.gradient.color="8421504" trailer.gradient.transparency="0" trailer.gradient.angle="0" trailer.brushmode="0" trailer.gradient.repetition.mode="0" trailer.gradient.repetition.count="0" trailer.gradient.repetition.length="100" trailer.gradient.focus="0" trailer.gradient.scale="100" trailer.gradient.spread="100" )
text(band=header alignment="2" text="Type" border="0" color="33554432" x="5" y="4" height="64" width="224" html.valueishtml="0" name=type_t visible="1" font.face="Tahoma" font.height="-10" font.weight="400" font.family="2" font.pitch="2" font.charset="0" background.mode="1" background.color="536870912" background.transparency="0" background.gradient.color="8421504" background.gradient.transparency="0" background.gradient.angle="0" background.brushmode="0" background.gradient.repetition.mode="0" background.gradient.repetition.count="0" background.gradient.repetition.length="100" background.gradient.focus="0" background.gradient.scale="100" background.gradient.spread="100" tooltip.backcolor="134217752" tooltip.delay.initial="0" tooltip.delay.visible="32000" tooltip.enabled="0" tooltip.hasclosebutton="0" tooltip.icon="0" tooltip.isbubble="0" tooltip.maxwidth="0" tooltip.textcolor="134217751" tooltip.transparency="0" transparency="0" )
text(band=header alignment="2" text="From" border="0" color="33554432" x="334" y="4" height="64" width="137" html.valueishtml="0" name=t_1 visible="1" font.face="Tahoma" font.height="-10" font.weight="400" font.family="2" font.pitch="2" font.charset="0" background.mode="1" background.color="536870912" background.transparency="0" background.gradient.color="8421504" background.gradient.transparency="0" background.gradient.angle="0" background.brushmode="0" background.gradient.repetition.mode="0" background.gradient.repetition.count="0" background.gradient.repetition.length="100" background.gradient.focus="0" background.gradient.scale="100" background.gradient.spread="100" tooltip.backcolor="134217752" tooltip.delay.initial="0" tooltip.delay.visible="32000" tooltip.enabled="0" tooltip.hasclosebutton="0" tooltip.icon="0" tooltip.isbubble="0" tooltip.maxwidth="0" tooltip.textcolor="134217751" tooltip.transparency="0" transparency="0" )
text(band=header alignment="2" text="To" border="0" color="33554432" x="814" y="0" height="64" width="96" html.valueishtml="0" name=t_2 visible="1" font.face="Tahoma" font.height="-10" font.weight="400" font.family="2" font.pitch="2" font.charset="0" background.mode="1" background.color="536870912" background.transparency="0" background.gradient.color="8421504" background.gradient.transparency="0" background.gradient.angle="0" background.brushmode="0" background.gradient.repetition.mode="0" background.gradient.repetition.count="0" background.gradient.repetition.length="100" background.gradient.focus="0" background.gradient.scale="100" background.gradient.spread="100" tooltip.backcolor="134217752" tooltip.delay.initial="0" tooltip.delay.visible="32000" tooltip.enabled="0" tooltip.hasclosebutton="0" tooltip.icon="0" tooltip.isbubble="0" tooltip.maxwidth="0" tooltip.textcolor="134217751" tooltip.transparency="0" transparency="0" )
column(band=header.1 id=1 alignment="0" tabsequence=32766 border="0" color="33554432" x="9" y="0" height="64" width="224" format="[general]" html.valueishtml="0" name=type visible="1" edit.limit=4 edit.case=any edit.autoselect=yes edit.autohscroll=yes font.face="Tahoma" font.height="-10" font.weight="400" font.family="2" font.pitch="2" font.charset="0" background.mode="1" background.color="536870912" background.transparency="0" background.gradient.color="8421504" background.gradient.transparency="0" background.gradient.angle="0" background.brushmode="0" background.gradient.repetition.mode="0" background.gradient.repetition.count="0" background.gradient.repetition.length="100" background.gradient.focus="0" background.gradient.scale="100" background.gradient.spread="100" tooltip.backcolor="134217752" tooltip.delay.initial="0" tooltip.delay.visible="32000" tooltip.enabled="0" tooltip.hasclosebutton="0" tooltip.icon="0" tooltip.isbubble="0" tooltip.maxwidth="0" tooltip.textcolor="134217751" tooltip.transparency="0" transparency="0" )
compute(band=detail alignment="0" expression="if (type = type[1] and getrow() < rowcount() and date_of_change[1] <= date_end, RelativeDate(date_of_change[1], -1), date_end )"border="0" color="33554432" x="837" y="0" height="64" width="347" format="[SHORTDATE]" html.valueishtml="0" name=date_to visible="1~tif (date_of_change = date_of_change [1] and type = type[1], 0, 1)" resizeable=1 font.face="Tahoma" font.height="-10" font.weight="400" font.family="2" font.pitch="2" font.charset="0" background.mode="1" background.color="536870912" background.transparency="0" background.gradient.color="8421504" background.gradient.transparency="0" background.gradient.angle="0" background.brushmode="0" background.gradient.repetition.mode="0" background.gradient.repetition.count="0" background.gradient.repetition.length="100" background.gradient.focus="0" background.gradient.scale="100" background.gradient.spread="100" tooltip.backcolor="134217752" tooltip.delay.initial="0" tooltip.delay.visible="32000" tooltip.enabled="0" tooltip.hasclosebutton="0" tooltip.icon="0" tooltip.isbubble="0" tooltip.maxwidth="0" tooltip.textcolor="134217751" tooltip.transparency="0" transparency="0" height.autosize=yes)
compute(band=detail alignment="0" expression="cumulativesum ( change_of_length FOR GROUP 1)"border="0" color="33554432" x="1417" y="0" height="64" width="215" format="[GENERAL]" html.valueishtml="0" name=installed_length visible="1~tif (date_of_change = date_of_change [1] and type = type[1], 0, 1)" resizeable=1 font.face="Tahoma" font.height="-10" font.weight="400" font.family="2" font.pitch="2" font.charset="0" background.mode="1" background.color="536870912" background.transparency="0" background.gradient.color="8421504" background.gradient.transparency="0" background.gradient.angle="0" background.brushmode="0" background.gradient.repetition.mode="0" background.gradient.repetition.count="0" background.gradient.repetition.length="100" background.gradient.focus="0" background.gradient.scale="100" background.gradient.spread="100" tooltip.backcolor="134217752" tooltip.delay.initial="0" tooltip.delay.visible="32000" tooltip.enabled="0" tooltip.hasclosebutton="0" tooltip.icon="0" tooltip.isbubble="0" tooltip.maxwidth="0" tooltip.textcolor="134217751" tooltip.transparency="0" transparency="0" height.autosize=yes)
compute(band=detail alignment="0" expression="if (date_of_change < date_start, date_start, date_of_change)"border="0" color="33554432" x="320" y="8" height="64" width="311" format="[SHORTDATE]" html.valueishtml="0" name=date_from visible="1~tif (date_of_change = date_of_change [1] and type = type[1], 0, 1)" resizeable=1 font.face="Tahoma" font.height="-10" font.weight="400" font.family="2" font.pitch="2" font.charset="0" background.mode="1" background.color="536870912" background.transparency="0" background.gradient.color="8421504" background.gradient.transparency="0" background.gradient.angle="0" background.brushmode="0" background.gradient.repetition.mode="0" background.gradient.repetition.count="0" background.gradient.repetition.length="100" background.gradient.focus="0" background.gradient.scale="100" background.gradient.spread="100" tooltip.backcolor="134217752" tooltip.delay.initial="0" tooltip.delay.visible="32000" tooltip.enabled="0" tooltip.hasclosebutton="0" tooltip.icon="0" tooltip.isbubble="0" tooltip.maxwidth="0" tooltip.textcolor="134217751" tooltip.transparency="0" transparency="0" height.autosize=yes)
column(band=detail id=2 alignment="0" tabsequence=32766 border="0" color="33554432" x="1915" y="8" height="64" width="352" format="[shortdate]" html.valueishtml="0" name=date_of_change visible="0" resizeable=1 height.autosize=yes edit.limit=0 edit.case=any edit.autoselect=yes edit.autohscroll=yes font.face="Tahoma" font.height="-10" font.weight="400" font.family="2" font.pitch="2" font.charset="0" background.mode="1" background.color="536870912" background.transparency="0" background.gradient.color="8421504" background.gradient.transparency="0" background.gradient.angle="0" background.brushmode="0" background.gradient.repetition.mode="0" background.gradient.repetition.count="0" background.gradient.repetition.length="100" background.gradient.focus="0" background.gradient.scale="100" background.gradient.spread="100" tooltip.backcolor="134217752" tooltip.delay.initial="0" tooltip.delay.visible="32000" tooltip.enabled="0" tooltip.hasclosebutton="0" tooltip.icon="0" tooltip.isbubble="0" tooltip.maxwidth="0" tooltip.textcolor="134217751" tooltip.transparency="0" transparency="0" )
column(band=detail id=3 alignment="1" tabsequence=32766 border="0" color="33554432" x="2304" y="8" height="64" width="288" format="[General]" html.valueishtml="0" name=change_of_length visible="0" resizeable=1 height.autosize=yes edit.limit=0 edit.case=any edit.autoselect=yes edit.autohscroll=yes font.face="Tahoma" font.height="-10" font.weight="400" font.family="2" font.pitch="2" font.charset="0" background.mode="1" background.color="536870912" background.transparency="0" background.gradient.color="8421504" background.gradient.transparency="0" background.gradient.angle="0" background.brushmode="0" background.gradient.repetition.mode="0" background.gradient.repetition.count="0" background.gradient.repetition.length="100" background.gradient.focus="0" background.gradient.scale="100" background.gradient.spread="100" tooltip.backcolor="134217752" tooltip.delay.initial="0" tooltip.delay.visible="32000" tooltip.enabled="0" tooltip.hasclosebutton="0" tooltip.icon="0" tooltip.isbubble="0" tooltip.maxwidth="0" tooltip.textcolor="134217751" tooltip.transparency="0" transparency="0" )
htmltable(border="1" )
htmlgen(clientevents="1" clientvalidation="1" clientcomputedfields="1" clientformatting="0" clientscriptable="0" generatejavascript="1" encodeselflinkargs="1" netscapelayers="0" pagingmethod=0 generatedddwframes="1" )
xhtmlgen() cssgen(sessionspecific="0" )
xmlgen(inline="0" )
xsltgen()
jsgen()
export.xml(headgroups="1" includewhitespace="0" metadatatype=0 savemetadata=0 )
import.xml()
export.pdf(method=0 distill.custompostscript="0" xslfop.print="0" )
export.xhtml()
Комментарии:
1. Вау, спасибо за подробный ответ! Я также переключился на начальные и конечные даты, используя хранимую процедуру. Я обязательно проверю это.
Ответ №2:
Вы имеете в виду, что в феврале (ваши даты приведены в формате DDMMYYY) длина для PT1 должна быть отрицательным числом, так что, если бы вы запускали отчет за первый квартал года, 2000 футов, удаленные в феврале, были бы вычтены из 2400 футов PT1, установленных в январе, для чистой установленной длины в 400 футов для PT1 за квартал? Если это так, вы могли бы сделать это как пересечение двух встроенных или постоянных представлений, одно для установок, другое для удалений, тип и (извлеченный) период времени являются столбцами объединения, вычитая удаленную длину для каждого типа за период из установленной длины для каждого типа за период, чтобы получить чистую установленную длину для каждого типа за период. Левое соединение между установками и удалениями.
Если вам также необходимо отслеживать удаление канала, который не обязательно был установлен вашей компанией — например, есть запись об удалении PT77, но нет записи об установке PT77, вы могли бы обратиться к этому как к ОБЪЕДИНЕНИЮ двух встроенных или постоянных представлений, одного для установок, другого для удалений, причем удаления преобразуются в отрицательные длины; затем вы бы преобразовали этот запрос UNION ALL во встроенное представление, где вы бы группировали по типу по периоду и суммировали длину.
Комментарии:
1. Спасибо за ответ, я немного прояснил свой ожидаемый результат. Я не хочу отслеживать, сколько было установлено за месяц, я хочу знать общее количество каналов, присутствующих в течение этого месяца. Я должен был сделать это более понятным.
Ответ №3:
Ваш пример результата, похоже, не имеет смысла. Это
Type From To Length
PT2 01/02/2011 28/02/2011 4000
PT1 01/02/2011 14/02/2011 2400
PT1 14/02/2011 24/02/2011 4400
PT1 25/02/2011 28/02/2011 2400
не показывает, сколько каналов PT1 было установлено ни за январь, ни за февраль.
Следующий запрос показывает общую длину канала, который устанавливался каждый месяц, по одной строке для каждого типа.
select type,
extract(year from installed) || '-' || extract(month from installed) as year_month,
sum(length)
from pipes
group by type, year_month
order by year_month, type
ВОЗВРАТ
PT1 2011-1 2400
PT2 2011-1 4000
PT1 2011-2 2000
Позже . . .
Для общей длины канала на любую заданную дату я бы, вероятно, использовал что-то вроде этого.
select p.type,
'2011-02-28' as effective_date,
(select sum(length)
from pipes
where installed <= '2011-02-28'
and type = p.type) as installed,
(select sum(length)
from pipes
where removed <= '2011-02-28'
and type = p.type) as removed
from pipes p
group by p.type, effective_date
order by type
Этот запрос возвращает
type effective_date installed removed
PT1 2011-02-28 4400 2000
PT2 2011-02-28 4000
Комментарии:
1. Спасибо за ваш ответ, я немного прояснил ожидаемый результат. Хотя некоторые каналы установлены в январе, они все еще присутствуют в феврале. Поэтому их необходимо учитывать.