質問
いテーブルと呼ばれOffDays、週末と祝日は維持されます。いテーブルと呼ばれLeadTimeる時間(日数)のための製品を製作することが格納されています。今年のテーブルという注文が商品のご注文日より保持されるものとします。
できるクエリの場合、製品が完成製造を使わずに保存手順やループ?
例えば:
- OffDaysは2008-01-10,2008-01-11,2008-01-14.
- LeadTimeは5製品9.
- 注2008-01-09製品9.
を計算します
- 2008-01-09 1
- 2008-01-10x
- 2008-01-11x
- 2008-01-12 2
- 2008-01-13 3
- 2008-01-14x
- 2008-01-15 4
- 2008-01-16 5
った場合にクエリー式を返し2008-01-16を使うことなく保存されている方によって算出してください私のアプリケーションコード.
編集はありません保管procs/ループ): その理由を利用できません保管手続を行うにサポートしていないデータベースです。できるだけ追加テーブル/データです。のアプリケーションは第三者の報告ツールのできるだけ制御するSQLクエリ。
編集(かんし): 私の現在の方法は、余分なカラムのテーブルの計算日は、予定のタスク/cronジョブ実行の計算を全て受注しみください。これは以下の理想いる理由はいくつかあります。
解決
形を生成することができますテーブルの事前クレジット決済可能
WDId | WDDate
-----+-----------
4200 | 2008-01-08
4201 | 2008-01-09
4202 | 2008-01-12
4203 | 2008-01-13
4204 | 2008-01-16
4205 | 2008-01-17
そのクエリーなど
SELECT DeliveryDay.WDDate FROM WorkingDay OrderDay, WorkingDay DeliveryDay, LeadTime, Order where DeliveryDay.WDId = OrderDay.WDId + LeadTime.LTDays AND OrderDay.WDDate = '' AND LeadTime.ProductId = Order.ProductId AND Order.OrderId = 1234
する必要があり、保存の手順とループのWorkingDaysテーブルのものではないが、定期的ます。でも少なく往復をサーバによりご利用の場合アプリケーションコードをカウントします。
他のヒント
最適なアプローチではカレンダーの表に示す。
そして検索するときのように:
SELECT c.dt, l.*, o.*, c.*
FROM [statistics].dbo.[calendar] c,
[order] o JOIN
lead l ON l.leadId = o.leadId
WHERE c.isWeekday = 1
AND c.isHoliday =0
AND o.orderId = 1
AND l.leadDays = (
SELECT COUNT(*)
FROM [statistics].dbo.Calendar c2
WHERE c2.dt >= o.startDate
AND c2.dt <= c.dt
AND c2.isWeekday=1
AND c2.isHoliday=0
)
いーす
RB.
で計算するアプリケーションコードを...くんくも醜いクエリにsql
こちらは片道利用のdateaddます。
くこの答えを表に示す。このなくなるわけではありませんが正しく動作のための長します。たので追加するだけの#のオフの日は見つかり、リードタイムを押して日付です。この問題の発生の原因になるのがオフの日の新しいです。
-- Setup test
create table #odays (offd datetime)
create table #leadtime (pid int , ltime int)
create table [#order] (pid int, odate datetime)
insert into #odays
select '1/10/8'
insert into #odays
select '1/11/8'
insert into #odays
select '1/14/8'
insert into #Leadtime
values (3,5)
insert into #leadtime
values (9, 5)
insert into #order
values( 9, '1/9/8')
select dateadd(dd,
(select count(*)-1
from #odays
where offd between odate and
(select odate+ltime
from #order o
left join #leadtime l
on o.pid = l.pid
where l.pid = 9
)
),
odate+ltime)
from #order o
left join #leadtime l
on o.pid = l.pid
where o.pid = 9
なぜを使用ループ?
//一部の擬似コード
int leadtime = 5;
date order = 2008-01-09;
date finishdate = order;
while (leadtime > 0) {
finishdate.addDay();
if (!IsOffday(finishdate)) leadtime--;
}
return finishdate;
このように思えるのでも簡単に機能している非ループです。
う~ん。oneソリューションできる店舗のテーブルの日のオフセットに基づきカウントのオフの日から年始にかけてでいます。2はoff。1/1/08いのオフセットの1(または0の場合のように開始0)です。1/3/08いのオフセットの2の数をスキップ1/2/08.からあり、その簡便な方法でチェックした。のオフセットの日程、追加のリードタイム、そのルックアップを算出しオフセットの末日です。
そのを作らずに別のテーブルを使用していますので、ソートの天井関数:各offdate、どのように多くの"日"の前に、相対的にご注文日より、サブクエリです。その後最多を注いでおります。をご利用日時に対応するのって余りを求めます。
このコードを特定すPostgreSQL、まことになるださい。
CREATE DATABASE test;
CREATE TABLE offdays
(
offdate date NOT NULL,
CONSTRAINT offdays_pkey PRIMARY KEY (offdate)
);
insert into offdays (offdate) values ('2008-01-10');
insert into offdays (offdate) values ('2008-01-11');
insert into offdays (offdate) values ('2008-01-14');
insert into offdays (offdate) values ('2008-01-18'); -- just for testing
CREATE TABLE product
(
id integer NOT NULL,
CONSTRAINT product_pkey PRIMARY KEY (id)
);
insert into product (id) values (9);
CREATE TABLE leadtime
(
product integer NOT NULL,
leaddays integer NOT NULL,
CONSTRAINT leadtime_pkey PRIMARY KEY (product),
CONSTRAINT leadtime_product_fkey FOREIGN KEY (product)
REFERENCES product (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
);
insert into leadtime (product, leaddays) values (9, 5);
CREATE TABLE "order"
(
product integer NOT NULL,
"start" date NOT NULL,
CONSTRAINT order_pkey PRIMARY KEY (product),
CONSTRAINT order_product_fkey FOREIGN KEY (product)
REFERENCES product (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
);
insert into "order" (product, "start") values (9, '2008-01-09');
-- finally, the query:
select e.product, offdate + (leaddays - ondays)::integer as "end"
from
(
select c.product, offdate, (select (a.offdate - c."start") - count(b.offdate) from offdays b where b.offdate < a.offdate) as ondays, d.leaddays
from offdays a, "order" c
inner join leadtime d on d.product = c.product
) e
where leaddays >= ondays
order by "end" desc
limit 1;
ここではPostgreSQLの書式にのっとった形でなされるべきで簡単に訳その他のSQL方言
--Sample data
create table offdays(datum date);
insert into offdays(datum)
select to_date('2008-01-10','yyyy-MM-dd') UNION
select to_date('2008-01-11','yyyy-MM-dd') UNION
select to_date('2008-01-14','yyyy-MM-dd') UNION
select to_date('2008-01-20','yyyy-MM-dd') UNION
select to_date('2008-01-21','yyyy-MM-dd') UNION
select to_date('2008-01-26','yyyy-MM-dd');
create table leadtime (product_id integer , lead_time integer);
insert into leadtime(product_id,lead_time) values (9,5);
create table myorder (order_id integer,product_id integer, datum date);
insert into myorder(order_id,product_id,datum)
values (1,9,to_date('2008-01-09','yyyy-MM-dd'));
insert into myorder(order_id,product_id,datum)
values (2,9,to_date('2008-01-16','yyyy-MM-dd'));
insert into myorder(order_id,product_id,datum)
values (3,9,to_date('2008-01-23','yyyy-MM-dd'));
--Query
select order_id,min(finished_date)
FROM
(select mo.order_id,(mo.datum+lead_time+count(od2.*)::integer-1) as finished_date
from
myorder mo
join leadtime lt on (mo.product_id=lt.product_id)
join offdays od1 on (mo.datum<od1.datum)
left outer join offdays od2 on (mo.datum<od2.datum and od2.datum<od1.datum)
group by mo.order_id,mo.datum,lt.lead_time,od1.datum
having (mo.datum+lead_time+count(od2.*)::integer-1) < od1.datum) tmp
group by 1;
--Results :
1 2008.01.16
2 2008.01.22
この を返しません 結果、受注するこ終了しました昨日offdaysテーブル(注3)で、必要なケアを挿入するoffdays。この受注などにoffdays.