【最大10000ポイント】当たる!!質問投稿キャンペーン!

テーブル1のデータを計算してテーブル2を作成したいと考えております。
計算については"数値"を更新日付の一つ前の値と引き算してその結果をテーブル2に挿入したいと思ってます。

テーブル1
ID 数値 更新日付
001 23 2008/02/23 2:00:00
001 34 2008/02/23 3:00:00
001 50 2008/02/23 4:00:00
001 23 2008/02/23 5:00:00
002 25 2008/02/23 3:00:00
002 50 2008/02/23 4:00:00
002 70 2008/02/23 5:00:00
002 50 2008/02/23 6:00:00

結果
テーブル2
ID 数値 更新日付
001 11  2008/02/23 3:00:00
001 16  2008/02/23 4:00:00
001 -27 2008/02/23 5:00:00
002 25  2008/02/23 4:00:00
002 20  2008/02/23 5:00:00
002 -20 2008/02/23 6:00:00

一応考えたのですが
SELECT *
FROM テーブル1 AS a, テーブル1 AS b
WHERE (((a.ID)=[b].[ID]) AND ((b.更新日付)=(select min(更新日付) from テーブル1 as b where a.更新日付 < b.更新日付)))
ORDER BY a.ID, a.更新日付);

として、aとbの数値を引き算しようと考えていますが、可能なのでしょうか?

ぜんぜん別の方法でもいいので教えていただけないでしょうか?

以上 よろしくお願いいたします。

A 回答 (1件)

前の質問を締め切らずに継続する質問をする行為は、「続きの質問」として、ここでは規約違反です。



RDBMS名とバージョンを明示するように求めましたが、なぜ提示がないのでしょう?せっかく具体的なSQLを提示しても、dekinaikunさんの環境では実行できない可能性があります。

>aとbの数値を引き算しようと考えていますが、可能なのでしょうか?

可能かどうかと言われれば、可能です。
しかし、RDBには、「前の行」や「後の行」という概念がないので、利用者側で通番を付けるといった工夫が必要になります。また、そういった操作は、SQLだけでやるより、ストアドプロシジャを使うとか、アプリケーション側でやる方が、シンプルだし性能も出せます。

以下のように、表定義やデータを格納するSQLを貼り付けておくと、アドバイスする側としてもすぐに検索SQLの作成に入れるので、多くの人から早くアドバイスをもらえると思いますよ。

1.表定義例
create table tbl1
(seqno int identity(1,1),
id int,
数値 int,
更新日付 datetime);

2.格納データ例
insert into tbl1(id,数値,更新日付) values(1,23,'2008/02/23 2:00:00');
insert into tbl1(id,数値,更新日付) values(1,34,'2008/02/23 3:00:00');
insert into tbl1(id,数値,更新日付) values(1,50,'2008/02/23 4:00:00');
insert into tbl1(id,数値,更新日付) values(1,23,'2008/02/23 5:00:00');
insert into tbl1(id,数値,更新日付) values(2,25,'2008/02/23 3:00:00');
insert into tbl1(id,数値,更新日付) values(2,50,'2008/02/23 4:00:00');
insert into tbl1(id,数値,更新日付) values(2,70,'2008/02/23 5:00:00');
insert into tbl1(id,数値,更新日付) values(2,50,'2008/02/23 6:00:00');

3.検索例
select
x.id,
x.数値-(select 数値
from tbl1
where seqno=x.seqno-1) as 数値,
x.更新日付
from tbl1 as x
where x.seqno>all (select min(seqno) from tbl1 where x.id=id)
order by x.id,x.更新日付
;
    • good
    • 2

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

関連するカテゴリからQ&Aを探す

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qmysql ひとつ上のレコード

恐れ入ります。
Mysqlにて、ひとつ上のレコードを参照し、
真であれば○○偽であれば××という処理をしたいのですが、どのような方法がありますでしょうか。

EXELで行うと、=if(A1=A2,"1","0") のような処理になります。
昇順で並び替えて、重複レコードについて処理を行いたいです。

よろしくお願いします。

Aベストアンサー

最近のバージョンならコレでいけるかと

select
(select A from テーブル where ID = TBL.ID1) A1
,
(select A from テーブル where ID = TBL.ID2) A2
,
A1=A2の比較式
from (
select T1.ID as ID1, MAX(T2.ID) as ID2 from
テーブル T1
LEFT JOIN テーブル T2
ON T1.ID > T2.ID
group by T1.ID
) TBL
;

QMAX値を条件にデータを取得するには?

SQL文で困っています。
ご教授下さい。


下記のようなデータがあった場合、それぞれの区分毎に
年月が最大(最新)のデータを取得したいです。
(実際には1レコードにその他項目があり、それらも取得します。)
<検索対象データ>
区分 年月   金額
-----------------------------
A   200412  600
A   200503  560
B   200311  600
B   200508  1000
B   200504  560
C   200508  400
C   200301  1100


<取得したいデータ>

区分 年月   金額
-----------------------------
A   200503  560
B   200508  1000
C   200508  400

よろしくお願いします。

Aベストアンサー

テーブル名をXXXとすると次のようなSQLでよいと思います。(最善の方法かどうかは自信がないですが)

select B.* from (select 区分, max(年月) as 年月 from XXX group by 区分) As A
inner join XXX as B on A.区分 = B.区分 and A.年月 = B.年月
order by B.区分

Q前のレコードの合計に現レコードの値を加えたいのです。

ACCESSを使っています。
たとえばひとつのレコードに車のデータとして
[日付]、[今日の走行距離]、[総走行距離]があるとします。

[今日の走行距離]は入力するとして、[総走行距離]
を前に入力した最終日の[総走行距離]に[今日の走行距離]
を加えた値を表示できないでしょうか。

Aベストアンサー

テーブルは[日付]、[今日の走行距離]だけをフィールドとして持ちます。そして名前はtbl1とします。
下のクエリーを使いえば、ご希望の結果になると思います。

SELECT T.日付, T.今日の走行距離, Sum(S.今日の走行距離) AS 総走行距離
FROM tbl1 AS T, tbl1 AS S
WHERE T.日付>=S.日付
GROUP BY T.日付, T.今日の走行距離
ORDER BY T.日付;

ただしテーブルに同じ日付のレコードが出てこない事が条件です。
なおデーターベースには一般にひとつ前のレコードという概念は無いので、この様な処理は表計算ソフト向きの様な気がします。

QSQLで特定の項目の重複のみを排除した全項目を取得する方法

私は仕事上でデータベースを扱っていて、タイトルのような処理を行う必要があるのですが、いかんせん方法がわからずネット上を検索しても同様だったためここで質問させていただきます。

質問点を簡単に説明いたしますと、
たとえばAというテーブルがあって、

項目名1 項目名2 項目名3 項目名4
 A    あ    ア    亜
 A    い    ア    以
 A    う    ア    宇
 B    え    イ    江
 B    お    イ    尾

上のような構造になっている場合に「項目名1」について重複している項目を排除し、結果として


項目名1 項目名2 項目名3 項目名4
 A    あ    ア    亜
 B    え    イ    江

上のようなデータを取得したいのです。
この時に、Aの重複を排除して取得するレコードは1~3行目のどれでもよいです。
また、データを取得する際には必ずそのレコードの「全項目」を取得したいのでDistinctはうまく使えませんでした。

どなたか詳しい方、方法を教えてくださると幸いです。回答お待ちしております。

私は仕事上でデータベースを扱っていて、タイトルのような処理を行う必要があるのですが、いかんせん方法がわからずネット上を検索しても同様だったためここで質問させていただきます。

質問点を簡単に説明いたしますと、
たとえばAというテーブルがあって、

項目名1 項目名2 項目名3 項目名4
 A    あ    ア    亜
 A    い    ア    以
 A    う    ア    宇
 B    え    イ    江
 B    お    イ    尾

上のよ...続きを読む

Aベストアンサー

比較可能で一意性のある値をもてる項目6をテーブルに追加して、

select T.* from T, (select Item1,min(Item6) as Item6 from T group by item1) W where T.item6=W.item6;

――ってやるのが、一番手っ取り早いと思います。
他のところに影響がでないのであればですが。
oracleならrowidを使うとか、レコードの更新時刻を突っ込むとか。

QSELECT 文 GROUP での1件目を取得

非常に初歩的な事で恐縮ですが、
以下のデータを抽出するsql文の書き方を模索しています。
環境:SQLSERVER2005

| 列1| 列2 |
+---+---+
| 1 | A |
| 1 | B |
| 1 | C |
| 1 | D |
| 2 | F |
| 2 | G |
| 2 | H |
| 3 | X |
| 3 | Y |
| 3 | Z |

上記のテーブルがあるとします。
列1でグループした値で、1レコード目の列2を抽出したいのです。
出力結果としては、

列1列2
+--+--+
1,A
2,F
C,X

としたいのです。
列1でGROUPしてしまうと列2の内容を集約しないといけないので困っています。
ご教授いたけないでしょうか?

Aベストアンサー

SQL Server 2005では、Oracleでいう分析関数が実装されています。

select
列名1,
列名2
from
(select
rank() over(partition by 列1 order by 列2) as rk,
列1,列2
from 表名) as x
where rk=1

Qテーブルからのselectにおいてデータの有無により結果をわけたい

id | point
----+-------
1 | 10
2 | 9
3 | 5
....
というテーブルがあるとします.
idを指定してpointを得たいのですが、そのidがこのテーブルに存在しない場合は空の結果ではなく0を返したいのです.
plpgsqlなどを使いif文で場合分けすればできることはわかっているのですがSQL文だけで(それもできれば1文で)これを実現する方法はあるでしょうか?
よろしくお願い致します。

Aベストアンサー

変則的ですが、これでよければidがユニークでなくても大丈夫ですし、集合関数を使わなくてもOKです。

select dm.id,case when ex1.point is null then 0 else ex1.point end from
(select ? as id) as dm left join ex1 on dm.id = ex1.id;

?を適当に変えてください。
chukenkenkouさんの発想はこれですよね。

Qテーブルの差分をとる結合

TableAとTableBがあります。構造は同じです。
中身は下記のようだとします。
TableA      TableB
ID VALUE     ID VALUE
1 A       3 C
2 B       4 D
3 C       

差分結合結果を下記のようにとりたいのです。
1 A
2 B
4 D

良い方法をご存じでしたら、ご教授よろしくお願い致します。

Aベストアンサー

SQL Server 2005 以降であれば、EXCEPT が使えるので、TableA - TableB と TableB - TableA の結果を UNION してやれば良いかと。
http://codezine.jp/article/detail/1304?p=2

例) --------------------------------------------------------------
(SELECT * FROM TableA
EXCEPT
SELECT * FROM TableB)
UNION ALL
(SELECT * FROM TableB
EXCEPT
SELECT * FROM TableA);
------------------------------------------------------------------

EXCEPT が使えないバージョンの場合は、 NOT EXISTS を使って差分を抽出してやれば良いでしょう。

例) --------------------------------------------------------------
SELECT * FROM TableA
WHERE NOT EXISTS (
SELECT 'X' FROM TableB
WHERE TableA.ID = TableB.ID AND TableA.VALUE = TableB.VALUE
)
UNION ALL
SELECT * FROM TableB
WHERE NOT EXISTS (
SELECT 'X' FROM TableA
WHERE TableA.ID = TableB.ID AND TableA.VALUE = TableB.VALUE
)
------------------------------------------------------------------

SQL Server 2005 以降であれば、EXCEPT が使えるので、TableA - TableB と TableB - TableA の結果を UNION してやれば良いかと。
http://codezine.jp/article/detail/1304?p=2

例) --------------------------------------------------------------
(SELECT * FROM TableA
EXCEPT
SELECT * FROM TableB)
UNION ALL
(SELECT * FROM TableB
EXCEPT
SELECT * FROM TableA);
------------------------------------------------------------------

EXCEPT が使えないバージョンの場合は、 NOT ...続きを読む

QSelect文で2つのフィールドを加算した結果を取得したい

Select文で2つのフィールドを加算した結果を取得したいと思います。しかし2つのフィールドのうち1つがNullの値だと残りのフィールドに値が入っていても空白(NULL?)で返ります。

[例]**********************************************
フィールドA:Null
フィールドB:300

SELECT フィールドA+フィールドB
FROM テーブルA

<Selectされた結果>
空白(何も表示されない。Null?)

[例]**********************************************

どのようにすれば、Nullでない値だけ取得できるでしょうか。

Aベストアンサー

SQL Server の場合は ISNULL() 関数を使います。

SELECT ISNULL(フィールドA,0) + ISNULL(フィールドB,0)
FROM テーブルA

QLAG関数に似た関数があればご教示ください。

いろいろ試行錯誤したのですが、ご質問させて頂きたいと思います。

以下のようなテーブルがあったとします。トランザクション形式です。
すべてのデータは数値型です。

ID seq time
A 1 10
A 2 5
B 1 25
B 2 30
C 3 20
C 3 10
C 3 20

以下のようにしたいと思います。
同一IDの中で一つ前の行のTimeをみて差分を出したいと思います。
以下のテーブルをみますと、IDがAのSEQ2番のtimeは5、
IDがAのSEQ1番のtimeは10です。なので5から10を引くと-5となります。
それをtime_diffにいれたいと思います。

ID seq time time_diff
A 1 10 null
A 2 5 -5
B 1 25 null
B 2 30 5
C 3 20 null
C 3 10 -10
C 3 20 -10

OracleではLAG関数があり、一つ前の行を参照することができ、今までそうしてましたが、SQL2005には同じような関数を探してもありませんでした。

仕方ないのでテーブルを別名保存し、timeフィールドをtime_lagと変更、そのテーブルに1行空行を追加し、オリジナルと結合させて
time同士を引き算してました。

しかし、この場合、あまりに負荷がかかり、ディスク領域も取ることから何か別の方法があればどうかご教示ください。

いろいろ試行錯誤したのですが、ご質問させて頂きたいと思います。

以下のようなテーブルがあったとします。トランザクション形式です。
すべてのデータは数値型です。

ID seq time
A 1 10
A 2 5
B 1 25
B 2 30
C 3 20
C 3 10
C 3 20

以下のようにしたいと思います。
同一IDの中で一つ前の行のTimeをみて差分を出したいと思います。
以下のテーブルをみますと、IDがAのSEQ2番のtimeは5、
IDがAのSEQ1番のtimeは10です。なので5から10を引くと-5となります。
...続きを読む

Aベストアンサー

#2です。

WITHはCTE(共通テーブル式)と言って、SQL2005から使えるようになりました。同じ記述が複数登場するようなケースで先頭に宣言します。

このCTEは一時テーブルではなく、tempdbに実体が作られるわけではありません。
(もちろん分析関数を使った時点で処理中にtempdbを使うのは避けられないわけですが)

>1000万件ではなく7億万件という笑えない大きさです。
これは後出しじゃんけんみたいなものですね。

結局LAGはなくても、LAGと同じ機能のものお望みということですよね。
であれば、SQL Serverにはありません。
たぶん、一時テーブルを使わない方法では先に書いた方法以外はないと思います。

正直知恵を絞る場所はLAGの代わりを探すことではなくて、7億件を一気に処理させないで済む方法を考えることだと思わなくはないです。

Q文字列をsplitするSQL文を教えて下さい

SQLServer2000上で指定した文字で文字列をsplitような関数があれば教えて頂けますか?

例えば"12345.6789"という文字列を"."(ピリオド)を指定して、"12345"と"6789"という2つの文字列を取得したいと思っています。

Transact-SQLの関数リファレンスを見てみたのですが、適当なものが見つかりませんでした。
自作するしかないのでしょうか・・

Aベストアンサー

見当たりませんね~。

declare @str1 nvarchar(1),@str2 nvarchar(50)
select @str1 =N'.',@str2 = N'12345.6789'
select
substring(@str2,1,charindex(@str1,@str2)-1) as 前,
substring(@str2,charindex(@str1,@str2)+1,len(@str2)-charindex(@str1,@str2)) as 後

こんな感じにしかできないみたいです


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング