質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

解決済

3回答

3676閲覧

SQL 以下の様な集計を行いたいのですがどのように実現すればよいのかで止まっています。

Yoshikatsu_

総合スコア47

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

1グッド

0クリップ

投稿2016/01/26 01:27

テーブルに 列 No,Name,Val があり以下のようになっているものとします。
No,Name,Val
1,'A',10
2,'A',11
3,'A',12
4,'B',13
5,'B',14
6,'A',15
7,'A',16
Nameの列が連続しているところは集計して以下の様な出力を期待しています。
No,Name,SUM_Val
1,'A',33
4,'B',27
6,'A',31

どのようなSQLで実現できるのかお知恵を拝借させてください。
DBはSQLServer2008R2です。
よろしくお願いします

退会済みユーザー👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

SQLServerの分析関数の使用例の
10. 連続範囲の最小値と最大値 (3人旅人算)
https://oraclesqlpuzzle.ninja-web.net/sqlserver2008-sql1-olap.html#1-10

と、キー項目がブレイクしたタイミングでサマリ集計するSQL
http://d.hatena.ne.jp/gonsuke777/20141202/1417527092

を見ながら作ってみました。
SQLServerの環境がないので、Oracle11gR2で作りました。

SQL

1with t(No,Name,Val) as( 2select 1,'A',10 from dual union 3select 2,'A',11 from dual union 4select 3,'A',12 from dual union 5select 4,'B',13 from dual union 6select 5,'B',14 from dual union 7select 6,'A',15 from dual union 8select 7,'A',16 from dual), 9tmp as( 10select No,Name,Val, 11No-Row_Number() over(partition by Name order by No) as Distance 12 from t) 13select Min(No) as No,Name,sum(Val) as Val 14 from tmp 15group by Name,Distance 16order by No; 17 18NO Name VAL 19-- ---- ---- 20 1 A 33 21 4 B 27 22 6 A 31 23

投稿2016/01/29 19:54

編集2019/03/12 06:34
AketiJyuuzou

総合スコア1147

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Yoshikatsu_

2016/01/31 11:22 編集

回答ありがとうございます。旅人算ですか? SQL見ただけでは理解できなかったので、参考URLを見てみます。 こんな方法でもできるんですね。
guest

0

こんな感じ↓
※TEST2を実テーブル名に置換して検証してください。

SELECT
I,
SUM(VAL)
FROM
(
SELECT
T.,
TEMP.I
FROM
TEST2 T,
(
SELECT
T1.
,
ROW_NUMBER() OVER(ORDER BY T1.NO) AS I
FROM
TEST2 T1
WHERE
(
T1.NO = (
SELECT
MAX(NO)
FROM
TEST2
)
)
OR EXISTS(
SELECT
1
FROM
TEST2 T2
WHERE
T2.NO = T1.NO + 1
AND T1.NAME <> T2.NAME
)
) TEMP
WHERE
T.NAME = TEMP.NAME
AND T.NO <= TEMP.NO
) T
GROUP BY
I

投稿2016/01/26 02:38

YiLi

総合スコア96

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Yoshikatsu_

2016/01/26 02:49

素早い回答ありがとうございます。 ROW_NUMBER() OVER(ORDER BY T1.NO) AS I として I でGroup Byですかこのような方法があるのですね。
guest

0

ベストアンサー

こんな感じでどうでしょう。各行について間に他のNameに割り込まれていない最小のNoをminNoとして求めてそれでgroup byしています。

SQL

1SELECT 2 t1.minNo, t1.Name, SUM(t1.Val) 3FROM ( 4 SELECT 5 No, 6 Name, 7 Val, 8 (SELECT MIN(No) 9 FROM t as b 10 WHERE 11 b.Name = a.Name 12 AND b.No <= a.No 13 AND NOT EXISTS 14 (SELECT * FROM t as c WHERE c.Name != a.Name AND c.No BETWEEN b.No AND a.No) 15 ) as minNo 16 FROM 17 t AS a 18) AS t1 19GROUP BY t1.minNo

投稿2016/01/26 02:04

crhg

総合スコア1175

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Yoshikatsu_

2016/01/26 02:30

素早い回答ありがとうございます。 Not EXISTS と BETWEEN をこんなふうに使うのですね。
Yoshikatsu_

2016/01/26 03:42

Where条件の見通しが良いのでベストアンサーとさせていただきました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問