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

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

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

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

Q&A

解決済

2回答

577閲覧

SQL 条件を複数指定して重複しないようにSELECTしたい

MUMU

総合スコア1

SQL

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

0グッド

1クリップ

投稿2022/07/15 15:29

実現したいこと

NO、NAME、DATEの三つの項目を持つテーブルからNAMEが重複しないようにデータを取得したいです。

取得時の条件は以下の2点です。
①NAMEが重複している場合、DATEが最新のものを取得する。
②NAMEもDATEも重複している場合はNOが大きいものを取得する。

NONAMEDATE取得したいレコード
1TEST12022/01/01
2TEST12022/01/01
3TEST22022/02/01
4TEST22022/03/01
5TEST32022/05/01
6TEST32022/04/01
7TEST42022/06/01
8TEST42022/08/01
9TEST42022/07/01
10TEST52022/09/01
11TEST52022/09/01
12TEST52022/09/01
13TEST62022/10/01

★のついているレコードが今回取得したいレコードです。

SQL

1CREATE TABLE [dbo].[TEST_TABLE]( 2 [NO] [nchar](10) NULL, 3 [NAME] [nchar](10) NULL, 4 [DATE] [date] NULL 5)

SQL

1INSERT INTO TEST_TABLE VALUES 2('1','TEST1','2022/01/01'), 3('2','TEST1','2022/01/01'), 4('3','TEST2','2022/02/01'), 5('4','TEST2','2022/03/01'), 6('5','TEST3','2022/05/01'), 7('6','TEST3','2022/04/01'), 8('7','TEST4','2022/06/01'), 9('8','TEST4','2022/08/01'), 10('9','TEST4','2022/07/01'), 11('10','TEST5','2022/09/01'), 12('11','TEST5','2022/09/01'), 13('12','TEST5','2022/09/01'), 14('13','TEST6','2022/10/01')

現状

SQL

1SELECT * FROM TEST_TABLE A 2WHERE EXISTS(SELECT 1 FROM TEST_TABLE B 3 WHERE A.NAME = B.NAME 4 AND A.DATE > B.DATE 5 6 ) 7 AND EXISTS(SELECT 1 FROM TEST_TABLE C 8 WHERE A.NAME = C.NAME 9 AND A.NO > C.NO 10 )

調べながらSELECT文を書いてみましたが、思うようにデータが取得できません。
上記のSELECT文では3行しか取得できない上に「TEST4」が重複してしまいます。

NONAMEDATE
4TEST22022/03/01
8TEST42022/08/01
9TEST42022/07/01

どのようにすれば条件を満たして取得できるでしょうか。
ご教示お願いいたします。

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

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

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

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

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

guest

回答2

0

ベストアンサー

下記でどうでしょう。

SQL

1SELECT 2 Max(A.NO) AS NO, 3 A.NAME, 4 A.DATE 5FROM 6 TEST_TABLE A 7 INNER JOIN ( 8 SELECT 9 NAME, 10 Max(Date) AS maxDATE 11 FROM 12 TEST_TABLE 13 GROUP BY 14 NAME 15 ) B ON A.DATE = B.maxDATE 16 AND A.NAME = B.NAME 17GROUP BY 18 A.NAME, 19 A.DATE;

投稿2022/07/15 16:49

hatena19

総合スコア33620

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

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

MUMU

2022/07/15 22:13

ありがとうございます! 期待した結果が取得できました。 NOとDATEの最大値をそれぞれ取得してINNER JOINするのですね! 迅速なご回答ありがとうございました!
guest

0

いろいろやり方はありそうですが、ROW_NUMBERを利用する方法がシンプルで個人的には好みです。

SQL

1SELECT * 2FROM ( 3 SELECT *, ROW_NUMBER() OVER (PARTITION BY NAME ORDER BY DATE DESC, NO DESC) RN 4 FROM TEST_TABLE 5) T 6WHERE RN = 1;

投稿2022/07/15 19:30

neko_the_shadow

総合スコア2225

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

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

MUMU

2022/07/15 22:13

ありがとうございます! 期待した結果が取得できました。 こんなにシンプルな書き方ができるなんて感動です! PARTITION BYは初めて知りました!勉強して使えるようにしたいと思います。 迅速なご回答ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問