TOP カテ一覧 スレ一覧 100〜終まで 2ch元 削除依頼
☆ 世界最速のデータベース SAS ☆
【Oracle】DB天下一武道会【MS-SQL】
【Pure】HSQL database engine【Java】
MySQL 5.0
ADO.NETの質問・雑談スレ2
【新型】SQLServer2005【またか】
【10g】オラクルマスター Silver Part3【11g】
【オラクル>ポストグレスの理由】⇒言い訳の為
はじまりです。
CSVファイルのスレ

SQL質疑応答スレ 19問目


1 :2019/05/23 〜 最終レス :2020/06/09
このスレは
「こういうことをやりたいんだけどSQLでどう書くの?」
「こういうSQLを書いたんだけどうまく動きません><」
などの質問を受け付けるスレです。

SQLという言語はISOによって標準化されていますが
この標準を100%実装したDBMSは存在せず、
また、DBMSによっては標準でない独自の構文が
追加されていることもあります。

質問するときはDBMS名を必ず付記してください。

【質問テンプレ】
・DBMS名とバージョン
・テーブルデータ
・欲しい結果
・説明

前スレ:
SQL質疑応答スレ 18問目
https://mevius.2ch.sc/test/read.cgi/db/1515071542/

2 :
SQL言語リファレンス一覧
Oracle Database
https://docs.oracle.com/cd/E96517_01/sqlrf/index.html
Microsoft SQL Server
https://docs.microsoft.com/ja-jp/sql/t-sql/language-reference
IBM DB2 Database
https://www.ibm.com/support/knowledgecenter/ja/SSEPGG_11.1.0/com.ibm.db2.luw.sql.ref.doc/doc/c0004100.html

PostgreSQL
http://www.postgresql.jp/document/current/html/sql.html
MySQL
https://dev.mysql.com/doc/refman/8.0/en/sql-syntax.html
https://dev.mysql.com/doc/refman/5.6/ja/sql-syntax.html


参考リンク
http://sql.main.jp/index.html
https://www.atmarkit.co.jp/ait/articles/0006/21/news001.html
https://oraclesqlpuzzle.ninja-web.net/
https://www.techscore.com/tech/sql/index.html/

3 :
過去スレ
18問目:https://mevius.2ch.sc/test/read.cgi/db/1515071542/
17問目:https://mevius.2ch.sc/test/read.cgi/db/1468157341/
16問目:http://echo.2ch.sc/test/read.cgi/db/1447160858/
15問目:http://peace.2ch.sc/test/read.cgi/db/1402919549/
14問目:http://peace.2ch.sc/test/read.cgi/db/1371476534/
13問目:http://toro.2ch.sc/test/read.cgi/db/1343899481/
12問目:http://toro.2ch.sc/test/read.cgi/db/1316769778/
11問目:http://hibari.2ch.sc/test/read.cgi/db/1299305530/
10問目:http://hibari.2ch.sc/test/read.cgi/db/1274791771/
9問目:http://pc11.2ch.sc/test/read.cgi/db/1252492296/
8問目:http://pc11.2ch.sc/test/read.cgi/db/1236253554/
7問目:http://pc11.2ch.sc/test/read.cgi/db/1223525474/
6問目:http://pc11.2ch.sc/test/read.cgi/db/1210940477/
5問目:http://pc11.2ch.sc/test/read.cgi/db/1193486961/
4問目:http://pc11.2ch.sc/test/read.cgi/db/1176553195/
3問目:http://pc11.2ch.sc/test/read.cgi/db/1160458216/
2問目:http://pc8.2ch.sc/test/read.cgi/db/1141622643/
帰ってきた:http://pc8.2ch.sc/test/read.cgi/db/1124178925/
Part 2:http://pc8.2ch.sc/test/read.cgi/db/1103113155/
初代:http://pc8.2ch.sc/test/read.cgi/db/1056973582/

4 :
よくある質問1

(問)
ID | DATE     | DATA
--+----------+-----
1 | 2007-11-11 | aaa
2 | 2007-11-11 | bbb
1 | 2007-11-10 | ccc
3 | 2007-11-12 | ddd
3 | 2007-11-11 | eee
4 | 2007-11-10 | fff
1 | 2007-11-12 | ggg

このようなテーブルから、下記のように

1 | 2007-11-12 | ggg
3 | 2007-11-12 | ddd
2 | 2007-11-11 | bbb
4 | 2007-11-10 | fff

各idに対して最新の1件だけ抽出するSQLの書き方を教えてください。

(答)
select A.ID,
    A.DATE,
    A.DATA
from TableName A
   inner join
   (select ID, max(DATE) as MAX_DATE
    from TableName
    group by ID
   ) B
   on A.ID = B.ID
   and A.DATE = B.MAX_DATE
;

5 :
よくある質問2

(問)
key   data
----------------
1     a
1     a
1     b
1     b
1     a
2     b
2     a
2     a

というテーブルから

key   a   b
--------------------
1    3   2
2    2   1

というExcelのピボットの様なデータを取得したいのですが、どういうSQLになりますか?
a,bというのは固定なので、仮にcというデータがあっても無視して構いません。

(答)
select key,
    SUM(CASE data WHEN 'a' THEN 1 END) AS a,
    SUM(CASE data WHEN 'b' THEN 1 END) AS b
FROM table
GROUP BY key
ORDER BY key
;

6 :
よくある質問3

(問)
ID HOGE
01 A
01 B
01 C
02 A
03 B

HOGEをAもBもCも持っている、ID:01だけ取り出すにはどうすればよかですか

(答1)
select id
FROM TableName
WHERE hoge in ('A','B','C')
GROUP BY id
HAVING count(DISTINCT hoge) = 3
;

(答2)
select *
from TableName T1
where not exists (select *
         from (values 'A', 'B', 'C') T2 (HOGE)
         where not exists (select *
                  from TableName T3
                  where T1.ID = T3.ID
                  and T2.HOGE = T3.HOGE
                  )
         )
;
※valuesの部分(Table Value Constructor)はDBMSによって文法がかなり違うので注意

7 :
よくある質問4

(問)
列の数が可変な問合せはどう書きますか?

(答)
標準SQLでは書けません。
pivotという機能を搭載したDBMSなら一見書けそうですが実はやっぱり書けません。
Oracle 11g以降でpivot xmlというキーワードを使用すれば一応可変っぽくはなります。
が、素直にプロシージャを書くかアプリケーションで処理したほうが良いでしょう。

SQL Serverのpivot(2005以降)
http://msdn.microsoft.com/ja-jp/library/ms177410.aspx

Oracleのpivot(11g以降)
http://download.oracle.com/docs/cd/E16338_01/server.112/b56299/statements_10002.htm#CHDCEJJE
http://www.oracle.com/technetwork/articles/sql/11g-pivot-097235.html

8 :
よくある質問5

(問)
年月(YYYYMM)を指定し、その年月に対応する年月日を取得したい

 例:201006を指定したら、以下の結果を得たい

   20100601
   20100602
    ・
    ・
    ・
   20100630

(答)
SQLでは存在しないデータを生成することはできません。
この問いの場合は素直にカレンダーテーブルを用意しましょう。

どうしてもやりたければ以下のような方法もなくはないですが、
再帰問合せの本来の使い方ではありません。
やめておくことを強くお奨めします。
(PostgreSQLの連番を生成する関数なら辛うじてセーフかもしれませんが
 賛否の分かれるところでしょう。)

with TEMP (NUM) as (
    select 1 from dual
    union all
    select NUM + 1 from TEMP where NUM < 31
)
select to_char(to_date('201006', 'YYYYMM') + NUM - 1, 'YYYYMMDD')
from TEMP
where to_date('201006', 'YYYYMM') + NUM - 1 < add_months(to_date('201006', 'YYYYMM'), 1)
;

※上記はOracleの場合です。(11gR2以降)
※再帰問合せをサポートするDBMSならこれを適当に改変すれば動きますが
 どのみちお奨めしません。

9 :
以上、テンプレ終わり

10 :
空文字列を入れたがるやつにかぎって、レコードによっては空文字列だったり、NULLだったりと両方想定してないといけない設計にして、運用ではまる。

11 :
苦労しているんだね
同情します

12 :
SQLじゃなくてテーブル設計の質問なんですが、お願いします。

商品を複数の倉庫に保管するモデリングなんですが、現状は、
----------------------------------------------------------------
pkey | 商品ID | 商品名 | 倉庫1 | 倉庫2 | 倉庫3 | 倉庫4 | 倉庫5 |
----------------------------------------------------------------
という風になって、保管する場所が増えるたびに、倉庫カラムが増える設計になっています。
これは、
-------------------------
pkey | 商品ID | 倉庫番号 |
-------------------------
    |      |   倉庫1  |
-------------------------
    |      |   倉庫2  |
-------------------------
    |      |   倉庫3  |
-------------------------
    |      |   倉庫4  |
-------------------------
    |      |   倉庫5  |
-------------------------

という風にするべきなのでしょうか?
最初の設計だとカラムが増えていくのに対して、この方法だとレコードがとんでもない数になっていくのですが・・・・

13 :
毎回思うけどレコード増えてなにが困るん?

14 :
>>13
@もともと1レコードに収まっていたデータを多数のレコードに分割すると、読み取りのパフォーマンスは落ちないでしょうか?
A副作用ですが、正規化することで、正規化前と比べてテーブル数が増える(20倍程度)と、結合で速度が落ちないか?
という点が不安です。

15 :
>>12
倉庫が増えたら項目増やさないといけなくなるのと
倉庫ごとに数量、単価、金額もちたくなるとさらに項目が増える

もとのデータは下のテーブル形式で、夜間処理で照会用の中間テーブルとして上のテーブルをつくればいい

16 :
>>15
おっしゃる通りです。経験のなさから、そこまで考えが及びませんでした。
まずは第三正規形に正規化した状態でのパフォーマンス確認からしてみます。

17 :
>>12
その商品、特定倉庫1ヶ所にしまうのかい?

18 :
SQL質疑スレでやるよりも、こちらでした方が良いかも

DB設計を語るスレ 10
https://mevius.2ch.sc/test/read.cgi/db/1495438711/

答える人は同じなんだろうけどね

19 :
縦横問題はRDBができて以来定番の課題&質問になってるな
PIVOTとかも使いにくいしいい加減DBMS側でうまいことしてほしいところ

20 :
今なら
「ラクテンスーパーポイントスクリーン」
登録するだけでRポイント150pが貰える!

※Androidアプリのみ
iPhoneユーザーはWeb版から登録のみ可能

登録完了後に表示される招待コ一ドをお持ちですか?のところで
「i9WPjs」
を入力する

完了

祭りだ♪ヽ('∀')メ('∀')メ('∀')ノワッショイ

21 :
>>14
あなたは30年前からタイムマシンに乗ってやってきたのですか?

22 :
>>21
30年前でもその設計はしないと思う

23 :
たまには30年先から来た人に話を聞いてみたい

24 :
>>23
過去には行けるが未来には行けない。これが現代の常識。

25 :
それだとおかしくなる

26 :
>>25
逆にだった。時間の流れが遅いところにいると、時間の流れが速いところに戻ったときに未来にたどりつく。

27 :
現在から過去に行けるなら、未来人が現在に来ることは可能だな

現代の常識だとそうなる

28 :
ここSQLスレじゃなくなったん?

29 :
SQLスレですね

30 :
今更だが、SQLの正しい記述ってのはあるのか?

31 :
今更だが、正しさとはなんだ?

32 :
アメリカが正義だ

33 :
標準SQLがBNF記法でまとめられてるサイト
https://ronsavage.github.io/SQL/

34 :
>>30
SQL:2016とかの規格の話?

35 :
>>34
はい。

36 :
https://i.imgur.com/QvQTuqJ.jpg

37 :
点数テーブル
名前 日付 点数
A  7/27 50
A  7/28 70
B  7/27 80
B  7/28 90

ゲタテーブル
A  7/27 10
A  7/28 -5
B  7/27 -20
B  7/28 5

というような2つのテーブルがあって
点数をプラスマイナスした結果を出力したいのですが、どういうやり方がありますか?
今UNION ALLして、名前と日付をGROYP BYして
点数をSUMで集計しているのですが、これで問題ないでしょうか?

本当は例よりもjoinjoinしていて複雑なので、文も大分長くなってますしこれでいいのか不安になってます

38 :
普通にleftjoinして加算すれば

39 :
ありがとうございます!
+で繋げたら普通に足し算できたんですね・・・お恥ずかしい
ゲタのほうに該当がなかった場合点数+NULLみたいにならないか不安ですが試してみます!

40 :
COALESCEなりCASEなりでNULLを0にすればいいんでない?

41 :
>>39
isnullつかえば

42 :
37の意図する事が今一分からないだが、
単純に点数テーブルとゲタテーブルをマージして
Group by して sum取っちゃ拙いのか?

MySQLだとこんな具合で
select `名前`,`日付`,sum(`点数`) from (
select `名前`,`日付`,`点数` from `点数テーブル`
union
select `名前`,`日付`,`点数` from `ゲタテーブル`
) g
group by `名前`,`日付`;

43 :
>>37がやってるってのがそれだろ。
しかも>>37は正しくunion all使ってるのにお前は間違えてるし。

44 :
>>43
あ、すまんな、その通りだ

45 :
まあunionでもいいと思うが万が一ゲタ側のレコードに対応するレコードが点数テーブルにない時もレコード出力されちゃうから俺ならleft joinでやると思う

46 :
>>37です。皆さんありがとうございます。参考になります
その後、LEFT JOINで書いたのですが、
点T
A 7/30 70
B 7/30 80

ゲタT
A 7/30 +10
A 7/30 -5
B 7/30 -10
というように、ゲタの対応するレコードが1件だけではなかったらしく
普通にLEFT JOINすると
A 7/30 80
A 7/30 65
B 7/30 70
のように複数行になってしまいました

サブクエリでSUMするしかないかなと考えているのですが
以下の2つのやり方でどちらが良いでしょうか?
後者のほうがシンプルで良いかなと思ってます
もしくは、もっと他に良い方法があるでしょうか?

@
SELECT 人, 日, 点+ゲタ計
FROM 点T
LEFT JOIN (
  SELECT 人, 日, SUM(ゲタ)
  FROM ゲタT
  GROUP BY 人, 日
)
ON 点T.人 = ゲタT.人
AND 点T.日 = ゲタT.日

A
SELECT 人, 日, 点+ゲタの合計
FROM (
  SELECT 人, 日, 点, SUM(ゲタ)
  FROM 点T
  LEFT JOIN ゲタT
  ON 点T.人 = ゲタT.人
  AND 点T.日 = ゲタT.日
  GROUP BY 人, 日, 点
)

見づらく恐縮なのですが、よろしくお願いします

47 :
2番目のgroup by はやばい.
正誤で言えば、1番目が正しい

48 :
ゲタハカセスギw

49 :
ありがとうございます!
確かにAはおかしかったですね・・・
@のほうで書いてみたいと思います
ありがとうございました!

50 :
サブクエリする必要はないけど
Aも別に間違いじゃないけどな
SELECT 人, 日, 点+SUM(ゲタ)
  FROM 点T
  LEFT JOIN ゲタT
  ON 点T.人 = ゲタT.人
  AND 点T.日 = ゲタT.日
  GROUP BY 人, 日, 点

51 :
>>47
なにがやばくてどう間違ってるのか詳しく

どう書いてもまあいいんだが、気になるなら実際のテーブル(インデックス)構成と件数で実行計画取ってみれ

52 :
date player score weekAve
2019-09-01 A 80 ?
2019-09-01 B 67 ?
2019-09-01 C 91 ?
2019-08-31 A 78 ?
2019-08-31 B 65 ?
2019-08-31 C 93 ?
2019-08-30 A 81 ?
2019-08-30 B 69 ?
2019-08-30 C 90 ?



というようなデータで、各プレイヤーのその日付段階での
直前1週間の平均scoreをweekAveのところに入れる方法をお願いします。

53 :
sqliteで作ったので適当になおしてくれ

select tb1.col1,tb1.col2,max(tb1.col3),avg(tb2.col3)
from tb1
left outer join tb1 as tb2
on tb2.col2=tb1.col2
and date(tb2.col1)>=date(tb1.col1, '-7 days')
and date(tb2.col1)<=date(tb1.col1)
group by tb1.col1,tb1.col2
;

54 :
>>53
大変ありがとうございました。
使わせていただきます。

55 :
name, datetime, comment のテーブルでnameとdatetime で主キーとしています。
nameが重複しているものだけをリストアップするにはどうすればよいでしょうか。

A 2019/9/20 0:0 AAA1
B 2019/9/20 0:5 BBB1
C 2019/9/20 0:5 CCC1
A 2019/9/20 1:0 AAA2
C 2019/9/20 1:5 CCC2
A 2019/9/20 2:0 AAA3

の場合以下を期待します。

A 2019/9/20 0:0 AAA1
A 2019/9/20 1:0 AAA2
A 2019/9/20 2:0 AAA3
C 2019/9/20 0:5 CCC1
C 2019/9/20 1:5 CCC2

以下のSQL文で実現できますが、もっとスマートな方法はないでしょうか?

select * from xxx
where name in
(
select name from
(select name, count(*) as cnt from xxx group by name)
where cnt > 1
)
order by name, datetime

56 :
HAVING使うぐらいか?

SELECT * FROM xxx WHERE name IN
(
SELECT name FROM xxx GROUP BY name HAVING 1<COUNT(*)
)
ORDER BY name, datetime

57 :
>>56
出来ました!
group by はhaving でしたね。
ありがとうございました。

58 :
こんなんでいいだろ

select *
from xxx T1
where exists (
  select *
  from xxx T2
  where T1.name = T2.name
  and T1.datetime <> T2.datetime
)

59 :
これはありえないw

60 :
テーブルのレコード数が多くてnameのカーディナリティも十分高いなら
一般には>>56より>>58の方が良いだろ。

61 :
DBMSとデータ量で実測してみないとわからんな。
NoSQL系なら58の方が速そう
RDBなら56を改変して
SELECT L.*
FROM xxx L
JOIN (SELECT name FROM xxx GROUP BY name HAVING 1<COUNT(*)) R
ORDER BY L,name, L,datetime
の方が速いかも

62 :
日時が同じデータはありえないという条件をいわれてないなら
普通はこんなsqlはかけないわw

63 :
> nameとdatetime で主キーとしています。

64 :
>>61
環境によるから実際に実行計画をみてみなきゃ確実なことは言えないのはその通りだけど、
そのsqlはサブクエリでfull scan 1回、外側で1回、nameのカーディナリティが高ければ
中間データも大きくなり、しかもJOINにインデックスが使われないときているから、
メモリに入りきらないようなテーブルの場合は極端に遅くなりそう。

65 :
nameのカーディナリティが高い場合、>>56>>61では中間データが大きくなり
メモリに乗り切らないことが考えられ、>>58のほうが速い可能性がある。

nameのカーディナリティが低い場合、>>58ではexistsの条件に早くひっかかる
可能性が大きくなり、やはり>>58のほうが速い可能性がある。

66 :
>>58は相関サブクエリにインデックスが使われ、datetimeの比較は2エントリ目で
必ず判断がつくから、実のところ速度はカーディナリティにあまり影響されない。

67 :
PostgreSQL 9.6.11 にて1000000行のデータでEXPLAIN ANALYZEを付けて実行してみた。データは https://ideone.com/WTthGi のようにして作成。
各8回実行し、最初の4回は捨てた。

>>55 PostgreSQLでは副問合せに名前を付けないとエラーになるため AS a を追加
Execution time: 1202.286 ms / 1173.974 ms / 1194.647 ms / 1221.041 ms

>>56
Execution time: 1164.661 ms / 1171.337 ms / 1210.060 ms / 1179.993 ms

>>58 order by name, datetimeを追加
Execution time: 2350.302 ms / 2320.161 ms / 2345.047 ms / 2368.932 ms

>>61 R の後にON L.name=R.nameを追加、ORDER BYの,を.に変更
Execution time: 1248.337 ms / 1215.495 ms / 1222.694 ms / 1222.818 ms

↑はDBや環境、実際のデータ、インデックスの追加で変わると思う。

68 :
>>67
素晴らしい。結局最初のであまり問題ないね
最近はよっぽど遅い場合を除いて
意図が分かるように書くのがいい感じよね

69 :
すいません
教えてください…
カラムは2つです(アクセスログです)
IP
CGI

複数種類あるCGIに対してどのCGIに
このIPからは何回、このIPからは何回アクセスされたというのを集計したいのですが
SQLが思いつきません…
だれか教えてください…

70 :
>>69
一旦各CGIがLogに出力して
日替わりや週替わり月替わりで集計したらどうか

71 :
>>69  select CGI,IP,count(*) from テーブル group by CGI,IP;

72 :
Windowsでデータベースを使いたく、今xamppをインストールして、PHPから学んでる最中なのですが、
mySQL(実際はMariaDB)で作ろうと考えていたのですが、私の目的のデータベースが作れるのか、調べてもなかなか出てこなくて、
ひょっとすると、リレーショナルデータベースでは出来ないのでは?と薄く疑問に思ってるのですが、、以下のデータベースを作ることは可能でしょうか?

例えば、プロゴルフ選手権のデーターベースを作るとします

選手の個人的な情報が入ったテーブル
(名前、生年月日、プロ登録年月日、所属チーム、性別等)

ゴルフコースの情報が入ったテーブル
(コース所在地、ホール数、ホールごとの距離、パー数、運営会社、プレイフィー、年次ごとの改修履歴等)

長年に渡るゴルフツアーの大会日程のテーブル
(カレンダー、使われたコース、個人成績、各順位の賞金額、賞金総額、スポンサー等)

このようなデータを連携させて、
ゴルフツアーのテーブルの個人成績の項目に個人データのテーブルとリレーションシップを張り、
ゴルフツアーのテーブルの開催コースの項目にコースのテーブルとリレーションシップを張り、

このデータベースを使って、例えば、
◯◯選手の年次ごとのツアー成績
◯◯選手の獲得賞金学の推移
◯◯選手のコース全長に対する成績傾向
特定のコースを得意とする選手
チームとして得意なコースか苦手なコースか

などの分析用のデータとして取り出したりすることは出来るものでしょうか?

accessをちょっと齧った程度の感覚ではできそうな気がするのですが

73 :
できる

74 :
>>72
そういうことをするためにリレーショナルデータベースは存在します。

75 :
>>73>>74
ありがとうございます
安心して勉強続けます

76 :
得意とか苦手とか、心の内面的な部分はどうSQLにしたら良いだろうね

77 :
その人の平均スコアより何%以上良ければそのコースは得意とか、そんなんじゃね?

78 :
数字のことはよく知らないけど、そういうのは平均値より偏差値が良いんじゃないの?

79 :
なぜ仕様の話になるのか?

80 :
宿泊人数を日毎に集計したい。
テーブル構成は、
ID(主キー)、チェックイン日、チェックアウト日、人数
(id, startdate, enddate, guests)
以下のデータがあるとき、
1, 2019/10/1, 2019/10/7, 4
2. 2019/10/2, 2019/10/3, 1
3, 2019/10/10, 2019/10/20, 2
2019/10/1:4人
2019/10/2:5人
2019/10/3:4人
2019/10/7:0人
2019/10/10:2人
2019/10/20:0人
このように、変化がある時点のみを抽出したいのですが、
どのようなSQLが考えられますか?

81 :
>>80
SQL-Server
select dates.date1 as date1, sum(coalesce(table1.guests, 0)) as guests
from table1
right join (
select startdate as date1 from table1
union
select enddate as date1 from table1
) dates on table1.startdate <= dates.date1 and dates.date1 < table1.enddate
group by dates.date1
order by dates.date1

82 :
>>81
ありがとうございました。

83 :
以下のURLのSQL練習サイトで勉強しているのですが
調べてもわからなかった問題があるので押してください。

■意味がわからなかった問題
https://sqlzoo.net/wiki/SELECT_within_SELECT_Tutorial/ja
の7番目、各大陸で最大

■問題の正解を出すSQL文

SELECT continent, name, area FROM world x
WHERE area >= ALL
(SELECT area FROM world y
WHERE y.continent=x.continent
AND area>0)

■教えていただきたい点

@SQLの解釈順序

 どのように上のSQLが解釈されているのか順を教えてください。
 
 こういう風に教えてくださいますと助かります。※以下の実行順は、私が考えたのですが、何かがおかしい感じがします・・・

  @()内のSQLを先に実行
  Aworld yテーブルの1行目のcontinentの値を見る。
  Bworld xテーブルの1行目のcontinentの値と見比べる。.continentの値が一致していたら、world yのarea の値を抽出する
  Cworld xテーブルのarea の値が、world yのareaより大きければ、world xのcontinent, name, areaを抽出する。
  Dworld yテーブルの2行目を見る・・・(以下行数を進めて繰り返し)


AほかのSQL文

 上の自己相関サブクエリと、以下のSQLで何か違いがあれば教えてください。
 (例えば、以下のSQLの場合、件数が数万件に及ぶと実行速度が極端に遅くなる等)
 select continent,name,area from world where area in (select max(area) from world group by continent)  



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

 

84 :
>>83
解釈としてはxとyの突き合わせだが
DBMSによってどう最適化するかは異なるから
実際は実行計画を見てみるしかない。
そのサイトの裏側が何だかわからないので手元で実行計画を見てみるといい
https://www.atmarkit.co.jp/ait/articles/0408/25/news101.html

85 :
>>83
簡潔に指摘するとALL句の意味を取り違えています。
ALL句の副問い合わせは同じ大陸内の国ごとの面積を返します。
area >= ALL は (area >= 面積1 AND area >= 面積2 AND area >= 面積3) のようなものです。つまりこの場合は一番大きい面積とarea列値を比べることになります。
あなたが考えた処理方法では、?はともかく?〜?を行っていまうと、最大の国だけでなく、同じ大陸の他のレコードまで取得してしまいます。

86 :
table1 親品番,子品番
table2 品番,品名
取り出したい内容
親品番,親品名,子品番,子品名
table1,2のjoinでON句に親品番=品番や子品番=品番とすると片方ずつは取得できますが、両方同時に取得することはできますか?

87 :
table1ひとつにtabl2をふたつJOINしてやればいいんだよ

88 :
>>87
ありがとうございます
週明けに試してみます

89 :
いかにも初心者らしい質問ですね

90 :
SQL Server 2014です。

文字列検索で、半角濁音および半角半濁音を含むかどうか調べたいです。
ただ普通に LIKE '%゙%' と検索すると全件ヒットしてしまいます。
照合順序で区別をしてもダメでした。

どうすればいいのでしょうか?(´・ω・`)

91 :
>>90
おそらく半角の濁点、半濁点が無視さらているのでしょう。

まずは自分が見ている濁点、半濁点の文字コードを調べてください。

92 :
照合順序なにでやってだめだったんだよ
バイナリ系のやつならいける気がするけど

93 :
キャラクタセットも自分で調べないようでは話にならない。

94 :
条件が半角カタカナ文字だったらどうなるのか書いてくれよ。

エスパーじゃないからわかんねえよ!

95 :
many to manyって中間テーブルつかわなあらわせないの?

96 :
べつに中間じゃなくてもいいよ。

97 :
どうやんの?

98 :
create table T (
a,
b,
unique(a, b)
)

これがaとbのmany to many

99 :
>>92
ありがとうございます。
照合順序で、てっきりCS・AS・KS・WSしか頭に入ってませんでした。
BINで判別できました。

100 :
マイク製品は大文字、小文字、全角、半角文字を同じのみなすからなあ。

変な仕様だけど、SQL Serverの照合順序を変えることが、SQLの質問なのか?

101 :
Microsoft SQL Server 総合スレ 12
https://mevius.2ch.sc/test/read.cgi/db/1534679537/

102 :
unique(a, b)
って何?

103 :
>>102
複合列の一意制約の構文だろうけど、どのRDBMSかは俺もわからない。

104 :
どのって、ふつうに標準SQLでしょ。

105 :
>>98は、見方によってはaとbの中間テーブルだがな

106 :
aとbの中間ってなんだそれ

107 :
>>106
服のうえから触るんじゃないの?

108 :
触るか触られないぎりぎりが良いの

109 :
ものすごく初歩的な質問すいません。

会社の業務で、OracleのデータベースからVBAを使って、データを取得しているようなのですが、この逆って出来るのでしょうか?
大量のExcelデータをVBAを使って、データベースを一気に書き換える、ようなスキルを身に付けたいと思っています。

また、このようなスキルを身に付けるにあたって、分かりやすい参考書のような書籍などありますでしょうか?

110 :
>>109
権限あればできるはず

111 :
一気に書き換えるってことは
DeleteしてInsertかな?
ODBC接続してSQL発行すれば良いのでは

112 :
>>109
古いExcel VBAの逆引き本に書かれている。ただ、正解はないのでどれが最適なのかは深く考えないこと。

113 :
>>110->>112
レスありがとうございます。

権限というのは、データベースに接続するためのID/PASSでしょうか?
Oracleのデータベースからデータを引っ張ってくるVBAの記述を見ると、「ID」「PASS」の
文字列があるので、これを利用できそうです。それともデータベースというのは
ID/PASSを知っているだけでは足りず、責任者の承認のようなものが一般的に必要と
なるのでしょうか?

「ODBC接続」「SQL発行」というのが、今目指していることのキーワードとなるようですね。
古い本に載っているそうですが、最新のものはありませんか?
それともネットのプログラミング講座を受講するのが早いでしょうか?

質問ばかりですいません。
よろしくお願いします。

114 :
>>113
そのID/PASSがテーブルを更新する権限があるかどうかが問題
てか、マジでそのデータベース管理してる人にそんなことして良いのか確認しなよ
ヘタこいてデータぶっ壊しましたテヘペロ
で済むならいいけど

115 :
普通DBの参照権限は貰えても更新権限は与えないよね。

116 :
そうだね
Excelで扱うデータを引っ張るような業務レベルだと
テーブル更新権限までは持たせないと思う

117 :
>>114->>116
そうですか…
せっかくスキルを身に着けたとしても、更新権限が付与されないのであれば意味がないですね。
おそらく管理者に確認しても、余計な事するな、となりそうなので

ただSQLの知識はあっても損はないので、買った本くらいは通読してみようかと思います。

118 :
ぶっちゃけ、そのヤろうとしてることはクラッキングだからな
管理者の許可を得ず、データにアクセスして改竄

119 :
家のPCでSQLSERVERとかPostgreSQLとか構築してみたら勉強になる
めっちゃ簡単だし

120 :
>>119
そんなことをしなくても、Excelシートをリレーショナルデータベースとして扱える。

121 :
まじっすか?

122 :
数百万レコード保存できるエクセルがあるそうです

123 :
ネタで言っている様にしか聞こえないw

124 :
>>122
100万レコードなら可能

125 :
unique cnstraintに引っかかるとエラーが帰ってくるの?

126 :
普通はそう

127 :
このエラーをtry exceptで例外処理して重複するのを防ぎたいんだけど
commitしないとエラーがでなくて
毎回addする毎にcommitするしかないですか?

128 :
既に存在する場合は登録しない様にすればいい

129 :
>>127
普通はコミットするまでにエラーがでると思うが
使ってる言語かDBMSのスレで聞け

130 :
売上を記録するテーブルの設計について教えて下さい。
例えば商品マスタが以下の構造だとします。
----------------------------
| 商品コード | 商品名 | 単価 |
----------------------------
販売履歴を記録するテーブルは、
  -----------------------------------
?| 商品コード | 商品名 | 単価 | 数量 |
  -----------------------------------
と、
  --------------------------
?| 商品コード | 単価 | 数量 | ※商品名は、商品コードをキーにしてマスタから取得
  --------------------------

  -----------------------
?| 商品名 | 単価 | 数量 | ※商品コードは、商品名をキーにしてマスタから取得
  -----------------------
の3つのどれがいいのでしょうか?

?の場合、販売後に商品コードが変わると、販売時の商品名が分からなくなり、
?の場合、販売後に商品名が変わると、販売時の商品コードが分からなくなるので、
?が一番いいのかな、と思うのですが、本当にそれでいいのでしょうか?

131 :
普通1だし、商品名変わったら新しくID発行するだけで上書きはしないよね。

132 :
普通は、商品コードと数量だろ?
(属性は足りないと思うけど)

133 :
その要件なら@で仕方ないと思うが、商品名の追跡が必要なら商品名ごとの
サブコードを発行しておくという手もあると思う。

134 :
何のために商品コードがあると思っているんだろうね。

135 :
値段の変動するものなら、その時の時価を記録してないと訳分からなくなるかも

136 :
SQLの話になってないぞ

137 :
どちらかと言うとDB設計スレの方が良いような

138 :
>>130
ずいぶん遅いレスだけど販売管理ならユーザーによって使い方が変わるからそういった点でも
できるだけ細かい情報を販売実績のテーブルに管理したほうがいいぞ

139 :
誰もがいつも表記の揺れのない正確な商品名を打てる世界を想定しなくはいけないのか?

140 :
>>139
イミフ

141 :
商品コードがなんのためにあるのかわかってない

142 :
DB設計スレに移動して続けたらどうかな

143 :
データに全ての情報を埋め込むのは汎用機システム世代
リレーションシップデータベース世代になるとマスターに
できるのはできるだけマスター化する
しかし全てマスター化すると古いマスターもずっと残さないといけなくなりマスターが肥大化してしまうのでデータに埋め込んでおくのもいい場合がある

144 :
リレーションシップデーターベース?

145 :
リレーショナルデーターベースとしても意末は通らんけど

146 :
正規化がたらんのやろ

147 :
>>130の商品コードと商品名が関数従属しないんならべつに@も非正規形ではないんだがな

148 :
ユーザーによっては商品マスタを使いまわすところもあれば商品ごとにマスタを登録するところもある
商品はセール(値引き)以外にも返品なども行う事もおおいから単純にマスタを見て単価や名称を紐づけすればOKなんて考えは
販売管理作ったことのあるやつならナンセンスじゃね
請求書や領収書なんかも変わった商品名称や単価だすとかありえんしね

149 :
>>148
あんた商売の素人だな。

150 :
テーブル設計の話題は 「DB設計を語るスレ」 でやってください

151 :
中間テーブルってプライマリキー無くてもいいの?

152 :
プライマリキーが無くてもいいテーブルがあるDBは設計が間違ってる。

153 :
じゃ全部プライマリキーってことか?

154 :
tempテーブルのこと言ってんでしょ?
それならプライマリキーなくても別に構わないよ

155 :
なんだろうtempテーブルって

156 :
えっ、temporaryテーブル(一時テーブル)のことだよ

157 :
釣れますか?

158 :
とりあえず設計スレ行けや

159 :
SQLスレにいるのにテンポラリテーブルも知らないのかw

160 :
SQLの仕様に、テンポラリテーブルってのが有るのか・・・

161 :
勉強し直してこなきゃ

162 :
ついでに名前が似てるテンポラルテーブルも

163 :
tempテーブルってのも調べて

164 :
一時テーブルという機能を持つDBMSはあるが、一時テーブルだとプライマリキーが要らない
理由なんてないよなぁ。

165 :
timpo table

166 :
意味的なプライマリキーと
DBMSのPRIMARY KEY制約がごっちゃになって話が混乱してるな

167 :
>>164
逆に一時テーブルの機能を持たないRDBMSってあるのかい?

168 :
Oracleは18cまでまともに使える一時テーブルがなかったのね
いろいろと納得

169 :
最初は中間テーブルって話だったのにいつの間に温度テーブルの話にすり替わったのか

170 :
温暖化の影響だろう

171 :
>>168
? 

172 :
>>166
それが混同されたとしても一時テーブルは関係ないわ

173 :
SQLのスレなんで、DBMSの実装機能の話は無いのかと思ってたが,そう言うことか

174 :
テンポラリテーブルはSQL-92で定義されてる標準だぞ
各実装が従ってるわけではないけど

175 :
おおっ!
そうなんだ
Thanks

176 :
inner joinの前と後のテーブル入れ替えても同じ意味になりますか?

177 :
>>176
同じ意味というのが
同じ結果セットが得られるかということならイエス
同じ実行プランが得られるかということなら必ずしもそうはならない

178 :
あ、inner join on x.id <> y.id のように不等号とか使ったら結果セットも変わるわ

179 :
二つのテーブルの内部結合なら不等号だろうが結果セットは変わらん気がするが
もちろん列指定ちゃんとやるって前提だが

180 :
順序が変わると言うことかも

181 :
順序は同じSQLですら変わっても文句言えない

182 :
べつに文句を言っている訳ではないよ
順序に期待するならそこまで考慮しようねって事

183 :
同じSQLですら結果の順序がどうなるかわからんのにinner joinの結合順で結果の順序とか言い出す奴って…

184 :
えっ??

185 :
>>183
そういう基本的なことからわかってないのにデタラメを言うやつは年齢関係なくいるから困るよね。

186 :
このスレでの話ならスルーしてれば何も困らないだろう
職場にいるんなら、それはお前がどうにかしろ
こんなとこで愚痴るなよ、鬱陶しい

187 :
いきなり何イキってるんだ?

188 :
2020みたいな西暦って
integerかstr かtimeのどれ型を使うのが一般的ですか?

189 :
年しかいらないならintegerとかの整数値だろ

190 :
そうすか ありがとうございました
int ならorder by できますからね

191 :
time型も内部表現は数値だったと思う

192 :
そういうことじゃないだろw

193 :
>>190
は?なんでもソートできるけど

194 :
>>188
最近はDate型にして月日には1月1日入れてる

195 :
日付形式にすると日付ではない値は
セットできないのでデータ整合性が
保てる
日付形式で困るのは最大値だな
データベースによって違うから
日付数字8桁なら99999999とかに
すればいいけど

196 :
西暦はゼロ年、1年の扱いの違いもちょっと困ることがある

197 :
年だけをどのデータ型にするのがいいのかは
利用方法、DBMSの種類、件数、(もしあれば)規約などによる
一般的にはint, smallint, dateが候補だけど
MySQLのようにyear型があればそれも選択肢になるし
Oracleならdateは7バイトも使うのであまり選ばれない
個人的には年だけ表現したいのに関数使わずに見ると
2020/01/01って入ってるのは嫌なのでsmallintが第一候補
過去の西暦とか入力できる範囲も違うから必要ならチェック制約使う

198 :
いまどき数バイトでどうこう言うのか?

199 :
1月2日とかが入るのを完全に排除できるならいいけど、それやるのにトリガとか使うくらいならintでいいよね。

200 :
>>198
数バイトが積み重なってレコード長が大きくなればパフォーマンスが徐々に悪化するからね

201 :
あっそう。

202 :
日付形式は検索するとき数字形式より遅くなる場合が多い
日付形式を検索するとき関数を使う場合が多く関数ある分遅くなる
例えばこんな感じ
Where TO_CHAR(sale_date, 'YYYY-MM-DD') = '1970-01-01'
俺は月次単位でデータを作る事が多く検索で多く使うから
年月は数字6桁でインデックス貼ってるな
年月は他のテーブルと連結する時も多く使われるので
後で変更する場合非常に面倒なのでよく考えたほうがいい
日付形式はデータ作成日時とか更新日時のではよく使う
パフォーマンス問題を引き起こす日付型
https://use-the-index-luke.com/ja/sql/where-clause/obfuscation/dates

203 :
日付型って内部は数値形式でしょう
比較したり順序を決めるのに文字列にする必要は無いんじゃないかな

204 :
OracleにはSQL-92 DATEが無かったからそんな感じだったな。

205 :
>>201
知らなかった感じ?
SQL使うだけなら知らなくていいけど
DB設計するなら基礎の基礎だから知っておくといいよ

206 :
とりあえずここはSQLのスレであってDB設計スレではない
そのことをまず知っておこう

207 :
>>202
どの製品のことを言っているのか?

208 :
>>205
馬鹿にされた自覚がないのか?

209 :
物理メモリもストレージ容量も大きいのに少しのことを大袈裟に言うやつは引退した方がいい。

ハードウェアの進化に知識が追いついていない。

210 :
>Where TO_CHAR(sale_date, 'YYYY-MM-DD') = '1970-01-01'

こういうダメな例を書かないためには
SQL使うだけのやつもDB設計の基礎知らないといけないんじゃないか?

211 :
自分の設計能力の低さをハード性能でカバーされてることに気づかないやつも引退したほうがいいけどな

212 :
>Where TO_CHAR(sale_date, 'YYYY-MM-DD') = '1970-01-01'

確にこれは初心者

213 :
ON DUPLICATE KEY UPDATEのIF文について質問させてください
ON DUPLICATE KEY UPDATE
fb_like = IF(fb_like > VALUES(fb_like), fb_like, VALUES(fb_like))
このIF分の第二と第三の引数と戻り値の意味を教えて頂けないでしょうか。
第一は比較条件なのは分かりますが・・・
DUPLICATE KEY UPDATEのリファレンスを調べてもわかりませんでした・・・

214 :
>>203
普通に考えて第2引数は条件が真の時に返す値で第3引数は偽の時に返す値でしょ
てか答え書いてあるだろ
> 取得した数字がレコードの数字より大きければ更新
https://qiita.com/yuzroz/items/f0eccf847b2ea42f885f

215 :
>>213
IFが分からないならON DUPLICATE KEY UPDATEじゃなくIF()関数のところを見ないと
https://dev.mysql.com/doc/refman/8.0/en/control-flow-functions.html#function_if

216 :
>取得した数字がレコードの数字より大きければ更新
取得した数字って書き方が悪いような

217 :
>>209
>物理メモリもストレージ容量も大きいのに少しのことを大袈裟に言うやつは引退した方がいい。
性能要求が低くてスケールする必要のない小規模・オンプレならそういう認識でいいかもねw

218 :
>>213
質問の内容自体はINSERT文にあまり関係ないというか単なるIF関数じゃないかな
IF自体はExcelのワークシート関数と同じく条件が真(True)なら第2引数、偽(False)なら第3引数の値を使う
でこれが今回のINSERT文になると
fb_likeに設定する値はUPDATE対象となるデータのfb_like(A)とVALUESで設定しようとしているfb_like(B)を比較して
A>BならAの値(何も変わらない)、そうでなければBの値になる
例えば最高得点を更新するような場合をイメージするといいかも
ただそれならA≧Bがよさそうではある

219 :
>>218
> ただそれならA≧Bがよさそうではある
価が変わらない時は更新しないような最適化はされるんだろうか?

220 :
>>219
MySQLのUPDATEは値が同じならUPDATEは実行されない

221 :
同じ値で更新するかどうかは製品の同時実行制御方式による。

多くの製品は同じ値でも更新してログを残す。
同じ値と異なる値で区別する方が実装が複雑になる。

222 :
primary keyが被って他のカラムが違った場合そこをupdateするのってどうやります?
ついでに旧の値も保存したいです。

223 :
primary keyが被るって、唯一無二のレコードじゃないのか?

224 :
「そこ」を使用する場合一意に決められるように文を定義してください

225 :
>>222
その主キー列は代理キーではないということか?
主キー列の値がレコードを区別するだけのものでない場合は、テーブルの設計が誤っている。

226 :
>>224
そこっていうのは非主キーのカラムです

227 :
primary keyを指定してアップデートする
「そこ」とは、primary keyになる
旧の値を保存したいなら、
更新の履歴をとっておくようにする

228 :
>>225
簡略化すると
商品というテーブルがあって
id(主キー)、名前、価格
というカラムで価格が変化するというような場合です
価格も主キーにするのがいいのですかね

229 :
元の質問の理解が難しいが複合主キーの第一キーをprimary keyと言ってるのかね

230 :
>>228
なんでインサートで新しいレコードを作らないのですか?

231 :
DB設計を語るスレ 10 [無断転載禁止]&#169;2ch.sc
https://mevius.2ch.sc/test/read.cgi/db/1495438711/
スレ違いが最近多いけど、設計スレは死んでるのか?

232 :
設計の話がなぜかSQLの話にすり替わるのは初心者の特徴なのだろうか?

233 :
リレーショナルデータベースの理論的な意味をすっ飛ばしてサロゲートキーあたりまえみたいな
教え方をするとこういうことになるといういい例。

234 :
>>233
よく読んだ?

235 :
>>230
同じidが被るのは良くないかなと思いました
あとどっちが最新の価格かもわからなくなると

>>231
>>232
すいませんでした移動します

236 :
「primary keyが被って他のカラムが違った場合そこをupdateするのってどうやります?
ついでに旧の値も保存したいです。」
こんな狂った質問はスルーでよかった。申し訳ない。

237 :
>>228
価格が変化すると言っても、商売の種類によって様々
生鮮食品を扱うとなればそれこそ日々変わるし
数年に一度価格見直しで一斉に変わるという業種もあるだろう
それによって設計も変わるし仕組みも変わる
相談したいなら、SQLの書き方を聞くスレではなく
DB設計の話題を扱うスレの方が相応しいと思うんだが

238 :
どうしてもkey を変えたくないなら元情報用カラムをついかして元情報をそこに残すしかし複数の変更履歴残したいならば、変更用トランザクションデータを残して置けば変更履歴は追える

239 :
テンポラルさんがスタンバってるよ

240 :
他システムが出力したデータをoracleのnumber(3,16)型のカラムに格納しています
もともとの値が浮動小数でそのまま出力して格納しているため、
96.3が96.29999999996や96.3000000000004のような値になっています
Oracleのsqlで、このカラムからnumber(3,3)の96.300の結果を得るにはどうすれば良いでしょうか?
アドバイスよろしくお願いします

241 :
ROUND()使えば?

242 :
>>240
number(3,3)にcastすればいい

243 :
number(3,3)って、全体で3桁、うち小数点以下3桁じゃなかったっけ?

244 :
>>240
NUMBER(整数+小数の桁数、小数の桁数)だぞ
左側が多くはず
number(3,16)型とかおかしい

245 :
ぶっちゃけ分かりにくいよね
その桁指定方法

誰が考えたのか知らんけど

246 :
FortranやCの出力フォーマット指定に準じているみたい
Fortran
f12.5 12桁で出力,うち5桁が小数点以下.
e20.7 科学的表記の20桁で出力,うち7桁が小数点以下.
C
%4.2fの4は全体の桁数、2は小数点以下の桁数

247 :
文章みればなんとなくわかるよね
まあわかってないのは質問者と>>240だけどw

248 :
COBOLなんて最悪のわかりにくさだけどな。

249 :
SQLとCOBOLって、殆ど同級生みたいなものだろう

250 :
>>249
まったく異なる

251 :
>>249
どこがどう「同級生みたいな」もんなんだよ。

252 :
SQL-86とCOBOL-85って殆ど同級生みたいなものだろう
って話じゃろうな

253 :
流れトン切り、雑談的な質問で恐縮なんだが
みんなコードを学んでいく上で周囲の人が書いたコード見たりして学ぶのかな
なんとなく盗み見るようで気がひけるんだけど
名前出てるからこの人の参考になるなという人の時々見てるけど、こそこそやってて落ち着かない
モラルの点でどう思う?

254 :
見れるところに置いてあるのなら、堂々と見れば良い

255 :
わかった、ありがとう
そうする

256 :
親ID 親Name 子ID 子Name ←列名
p1 pn1 c1 cn1
p1 pn1 c2 cn2

現在、クエリで上記の形で取得できているのですが、これを
ID Name IsParent
p1 pn1 true
c1 cn1 false
c2 cn2 false

のような形で取得することはできますか?
DBはoracle11gR2です

257 :
(
select distinct 親ID as ID, 親Name as Name, true as IsParent from テーブル
) union all(
select distinct 子ID as ID, 子Name as Name, false as IsParent from テーブル
)

258 :
>>253
他人のものをよく見て、真似るのが基本中の基本。
さらに自分の中でも試行錯誤を繰り返す。
これをずっとやらないとコピペプロクラマにしかなれない。

259 :
>>257
ありがとうございます
union allという手がありましたね。それで検索してみたら↓のようなのを見つけたので色々と試してみたいと思います!
https://www.oracle.com/technetwork/jp/articles/otnj-sql-image7-1525406-ja.html#d

260 :
p1 pn1 c1 cn1
p1 pn1 c2 cn2
p2 pn1 c5 cn5
p2 pn1 c6 cn6
p3 pn1 c3 cn3
p3 pn1 c4 cn4
だったらどう取りたいのかが少し気になったわ
必ず親の次に子をとるなら・・・

261 :
親の次とか意味が分からんけど、それより
p1 pn1 c1 cn1
c1 cn1 p1 pn1
とかあったらどうするんだろね

262 :
そもそも >>256 は何を言っているのかまったくわからない。
親子とはなんなんだ?

263 :
>現在、クエリで上記の形で取得できているのですが
これから推測するに、元となるテーブルが一つ、二つあって
それからクエリ使って2行の例を導いたと思われる
だとすれば、元となるテーブルデータと取得したクエリを公開すれば
質問に対する適切なアドバイスを得れると思うが、本人は既に解決済と見える

264 :
>>256です
たしかに前提条件も詳細な情報もなく
ほかの人から見れば分からないことだらけですね すみません
だいたい>>263の通りですが、あまり時間が取れてなくて解決していませんでした

>>260
IDが違えば基本的には名前は被らないですが、その例だと
p1 pn1 true
c1 cn1 false
c2 cn2 false
p2 pn1 true
c5 cn5 false
c6 cn6 false ...と取りたいです

>>261
循環はないようなテーブルですが、それを規制するものはないため、
クエリ側で循環の対策が必要ですね

265 :
親子とは商品で例えると、セット品のようなもので
子がいない(セット品ではない)ものは子品番がNULLになっています
複数テーブルですが、一つにまとめて簡素化したものが以下になります

https://ideone.com/VRo2S0

ほしいデータは Where 注文番号 = 101だとすると、
品番 品名 親か
P001,親1,true
C001,子1,false
C002,子2,false
C003,子3,false
P002,親2,true

今までは普通にSampleテーブルのような形で取得し、
プログラム側で処理していたのですが、SQLでデータ整形ができるなら
(作り直している)プログラム側がスッキリするなと思いまして質問しました

266 :
子が親になるケースもあるなら
unionした結果をID(と名前)でgroup byしてcase式使って集約

でもSQLで処理するとプログラム側で親子関係が見えなくなるから
1つの注文に対するデータ件数が十分少ないなら
SQLじゃなくプログラム側で処理したほうが柔軟性が高くていい気がする

267 :
>>264
失礼。名前は直しわすれましたわ
そうなるとこんなかんじじゃないかね
select ID,Name,IsParent from(
 select 親品番 as ソートキー1,1 as ソートキー2,親品番 as ID,親品名 as Name,true as IsParent from Sample where 注文番号 = 101
 union all
 select 親品番 as ソートキー1,2 as ソートキー2,子品番 as ID,子品名 as Name,false as IsParent from Sample where 注文番号 = 101
) as TB order by ソートキー1,ソートキー2,ID

268 :
いつもながらエスパーがいるね

269 :
DBMS名とバージョン
MySQL 5.6

テーブルデータ

shops
id | name
------------
1 | shopA
2 | shopB
3 | shopC

270 :
DBMS名とバージョン
MySQL 5.6

テーブルデータ

shops
id | name
------------
1 | shopA
2 | shopB
3 | shopC

rates
id | shop_id | rateA | rateB
-----------------------------
1 | 1 | 0.1 | 0.05
※ rateA, rateB は total_price に掛けるパーセンテージ。小数点切り捨て

orders
id | shop_id | type | name | price
-----------------------------------
1 | 1 | A | nameA | 100
2 | 1 | B | nameA | 200
3 | 1 | A | nameB | 50
4 | 2 | A | nameB | 300

欲しい結果
shop_name | type | total_price | x_rateA | x_rateB | exist
----------------------------------------------------------
shopA | A | 150 | 15 | 7 | 1
shopA | B | 200 | 20 | 10 | 1
shopB | A | 300 | 30 | 15 | 1
shopB | B | 0 | 0 | 0 | 0

説明
ordersを集計した結果が欲しいです。そのときordersテーブルが持っているtypeをshopごとに持たせたいです。つまりshopBはtypeBのorderを持っていませんが、集計結果にはtypeBも結果に入ってきてほしいです。
ほかに、ordersを集計しratesテーブルのレートを掛けたものをx_rateA,x_rateBとして集計してほしいです。
existはorderがあったかどうかの0,1です。

よろしくお願いします。

271 :
SQLはりつけられなかったわ
結局typeはordersにしか情報がないなら
select type from orders group by type
でtypeテーブルを作る
それをshopsと直積で結合してその状態から
ratesとordersを結合して集計すればいいんじゃないの
existsは結合したordersのshop_idがnullなら0それ以外なら1

272 :
>>267
1番目のselectでは同じ親品番が複数出てくるためDistinctを追加し、
union allの次のselectでは子品番のnullが出てくるためis not null を追加したところ
目的のデータが取得できました
ソートキーを入れる発想が思い浮かばなかったです
ありがとうございました

273 :
なんか中継クラウドでチェックが入りインジェクションと見なされるみたい
ソースアップロードサイトに上げて、リンク張ればいいかも

274 :
ここ最近Oracle使ってないから覚えてないけど
今回みたいなのはSQL1回でガチャガチャやるよりも
ストアドプロシジャで結果セット返すようにして
テンポラリテーブル作る
親データINSERT
子データINSERT
ソートして結果を返すってやったほうが自分はいいとおもってるけどね
269もtype欲しさに受注データをgroupbyとかほんとはやりたくないわ
ABしかないならそれ用のテンポラリテーブル作って結果を返すストアド作ったほうがいい気がする

275 :
SQL Serverでは安易にできるけど
MySQLってストアドで結果セット簡単に返せたっけ?
Oracleはメッチャ大変だった記憶

276 :
>>270
地味に面倒くせぇ
https://www.db-fiddle.com/f/dQVqiZLJu6ntVKUtaKNSKM/1

277 :
>>276
おおお!ありがとうございます!!
すごい。

もし、shopCも入れる場合にはどのようにすればいいですか?typesとCROS JOINだと思うのですが、うまくできませんでした。
欲しい結果
shop_name | type | total_price | x_rateA | x_rateB | exist
----------------------------------------------------------
shopA | A | 150 | 15 | 7 | 1
shopA | B | 200 | 20 | 10 | 1
shopB | A | 300 | 30 | 15 | 1
shopB | B | 0 | 0 | 0 | 0
shopC | A | 0 | 0 | 0 | 0
shopC | B | 0 | 0 | 0 | 0

278 :
>>277
ordersに入っていないshop名をshopsから取得すればできるんじゃないか

279 :
こんな応用も考えられないやつがSQL使うんだな
業務のSQLだったら恐ろしいわ

280 :
>>278
https://www.db-fiddle.com/f/iFRAaUckQWb7FXKb3GRcC4/0
できました。ありがとうございます。
>>276
inner join (select distinct shop_id from orders) as shop_ids
この行は動きとしては cross join なんですね。
ordersのすべてのtypeと、ordersのすべてのshop_idをかけ合わせたベースとなる表をつくり、それ対して1:1になるshopsとratesをinner joinでくっけたあとに、そこにordresをで肉付けするようなイメージなんですね。
そしてsumなどの集計関数があるのでgroup byで集計する単位を決めているんですね。
勉強になりました。

281 :
自作自演か

282 :
>>280
>inner join (select distinct shop_id from orders) as shop_ids
>この行は動きとしては cross join なんですね。
その通り
join/inner joinにonなどで条件を付与しなければcross joinになる
意図を伝えるためにはcross joinと書いたほうがよかったかもね

283 :
onかかないinner joinって標準SQLで許可されてる?

284 :
結合条件の指定がないってだけだから、許されると思う

285 :
MySQLとOracleのマニュアル見てみたら省略可能になってるけど
ISO/IEC 9075-2:1999だと省略マークないね
結構いろんなDBMSで直積使ったけどエラーになった覚えははないな

286 :
>>285
SQLSERVERでエラーになったような

287 :
ネタだから付き合う必要はないよ。彼の最近のトレンドは直積。書き込みをよく見れば直積に絡む話ばかりだとわかる。

288 :
onが必要な場合
on 1=1
とすれば同じ

289 :
>>287
270だけどはじめてここに来たよ。
とても助かって感謝している。

290 :
感謝はいいけど
どういう風に理解してくれたかだよな
次に生かせないでまた質問するだけならもうやめたほうがいい

291 :
また聞けばいいだけだろう

292 :
>>290

>>270での質問の仕方だったり
>>280の自分の理解をフィードバックする姿勢だったり
この手のスレでは珍しいくらいのまともな質問者だろ

それに対してケチつけることしかできないなら
君は人間をもうやめたほうがいい

293 :
ここで質問してくるやつは目的を書かないからタチが悪い。

294 :
読解力がないのを人のせいにされても……

295 :
■EXISTSを使用して。

データベース:オラクル

・氏名テーブルの姓、名前を検索情報にして以下の国語テーブル、算数テーブル、
英語テーブルからやまだたろうの、最高点を1レコード抽出するSQLのご教授を
お願いいたします。
※「EXISTS」を使用した、SQLのご教授をお願いいたします。
※英語は最高点が70点と2レコード存在しますが、
1レコードのみを抽出したいです。

■氏名テーブル(主テーブル)
姓 名前
やまだ たろう

■国語テーブル
姓 名前 点数
やまだ たろう80
やまだ たろう90
すずき しろう90

■算数テーブル
姓 名前 点数
いのうえ いちろう20
やまだ たろう50
やまだ たろう90

■英語テーブル
姓 名前 点数
しばた じろう20
やまだ たろう70
やまだ たろう40
やまだ たろう70

▼結果(1レコードのみ出力)
姓 名前 国語の点数 算数の点数 英語の点数
やまだ たろう90 90 70

宜しくお願いいたします。

296 :
宿題は自力でやれ

297 :
せめて、
こうやって見たけどうまく行かない、どうしたらいい?
みたいに、質疑出来るようにして欲しい

298 :
なぜにEXISTS ??
このケースで普通使わんやろ

299 :
最高点抽出するってんなら使うこともあるだろ

300 :
maxの代わりか
実践で使うことはまずないな

301 :
この条件でEXISTSはどうやってつかうんだ?

302 :
not exists (自分より点数高い奴)
昔はmax()使うより良い実行計画吐くことも多かったんでよく使われた。

303 :
氏名テーブル関係なくて笑うわ

304 :
https://stackoverflow.com/questions/18661642/using-exists-to-find-rows-with-maximum-value

305 :
さんくす勉強になったわ

306 :
>昔はmax()使うより良い実行計画吐くことも多かったんでよく使われた。
今となってはバッドノウハウ感満々だな
>>295がどこからこんなお題を持ってきたかが気になるわ

307 :
今でもmaxだけで常に最適な計画が得られる保証はないわけだし、
引き出しとして持っておいて損はないと思うがな。

308 :
まあ、引き出しとして持っといて損はないんだろうけど
実行計画いじりたいならまずヒントで何とかならんか検討すべきだしな

309 :
ヒントって、SQLチューニングでも期待通りにならない場合に使う最後の手段って印象だが。

310 :
そもそもチューニングだのなんだの、
SQLを歪めてまでパフォーマンス気にしなきゃいけないDBが欠陥商品なんだよなぁ
安いモノでもないのに

311 :
誰か exists と max で検証してみて
その上で議論しないと空回りするよ

312 :
昔はそういうテクも有効だった
今どきはそう言うテクを使う必要は激減してるから使わなくていい、と言うかわかりにくいから使うな
要するに今は極々稀に役に立つかもしれないバッドノウハウ

313 :
not existsはもう少し改善できる余地あるかもしれないが
distinct必要になるし単純なmaxより優れたプランになる可能性は感じられない
http://sqlfiddle.com/#!4/08250/4

314 :
相関サブクエリはふつうnested loop joinになるが、index張ってないと最悪。
適切なindexを張っていれば集約関数を使う場合よりもfull scanの回数を抑えられる可能性はあるが、
ful scan自体大してかからないような小さいテーブルだと効果はない。

315 :
>>314
>相関サブクエリはふつうnested loop
いまどき信じられんが

316 :
適切なindex張ってれば集約関数もindex使うから関係ない
余程間抜けな集約関数使ってる時代遅れのDB以外ではバッドノウハウ

317 :
oracleって連結したテーブルはupdateできないとかあって
existsを使わないといけないケースが多いな
それ以外はexistsは使わないほうがいい

318 :
>>317
その理由は?

319 :
遅いとかなんとか

320 :
maxの代替で使うのがバッドノウハウってだけで
exists自体は別に使いたければ使えばいい

321 :
>>318
existsはレコード件数ごと参照テーブルの検索が行われるため遅い
inner joinやleft joinで置き換え可能下記URL参照
http://kkoudev.github.io/blog/2013/09/14/sql/
特に not existsは、参照テーブルを前件検索しないと 存在しない事がわからないので特に遅いと思う

322 :
マシンパワーで解決できる場合は良くないとされるる
EXISTSやINとかのほうが意図が分かり易いから使っちゃう

323 :
>特に not existsは、参照テーブルを前件検索しないと 存在しない事がわからないので特に遅いと思う

indexがない前提かな?

324 :
今どきの賢いDBMSのオプティマイザなら、相関サブクエリとJoinとで同じ実行計画立ててるぞ

まあ、すべてでうまく置き換えてくれるわけではないが
相関サブクエリを速度対策のみのJoinに置き換えるのもそろそろバッドノウハウ行きだ

325 :
>>321
それはDBMSとオプティマイザ次第だから実行プラン見たほうがいいぞ
LEFT JOIN+NULLチェックよりもNOT EXISTSのほうが効率いいケースは普通にある

326 :
ちょっと古いけどSQL Serverでの比較
https://sqlperformance.com/2012/12/t-sql-queries/left-anti-semi-join
シンプルなクエリならオプティマイザが置きかえてくれるだろうけど
複雑になるにつれて変換されない可能性が高くなるからちゃんと確認したほうがいいと思うよ
maxの件とは種類が違う

327 :
SSMSで実行計画の視覚化めっちゃ参考になるんだけど
Oracleで似たようなことできるツールないかなあ

328 :
まずは視覚化の意味から勉強しろよ!

329 :
可視化っ事を言いたいのかな?

330 :
可視化の方がよく使われるけど視覚化と言う言葉もあって別に意味的にはおかしくない
むしろ>>328-329のツッコミが意味不明
https://dictionary.goo.ne.jp/word/%E8%A6%96%E8%A6%9A%E5%8C%96/

331 :
いや、もともと見えているという指摘だ。

332 :
誰か>>331に話の流れを視覚化してやってくれw

333 :
SSMSの実行計画表示みたことあるのか?
あれは他のDBでも欲しいよな
SQLSERVERの実行計画ってxmlで保存してあとからSSMSで表示できるはずだから
実行計画のコンバーター作れば良い感じにならんかなぁ

334 :
Oracleで実行計画を見る方法はたくさんある

一番基本的なのはexplain planかSQL*Plusのautoexplain
ただこれはテキストベース

一番凝ってるのはEnterprise Managerで見る方法
これはグラフィカルに見ることが出来る
Enterprise EditionとTuning Packが必要だが

335 :
りんご 3
バナナ 1
というテーブルから
りんご
りんご
りんご
バナナ
の出力を得たいです
個数分出力することはできますか?

336 :
Postgresならgenerate_series使うと簡単にできる
CTE使えばどのDBでもできると思うけど
わざわざSQLでやるようなものじゃない

http://sqlfiddle.com/#!17/ed939/1

337 :
ちょっと変なSQL作りたいならDBは何かを書いたほうがいいと思うの
ちなみに俺が使ってるDBならできる

338 :
めんどくさい時はプロシージャ書いてしまう

339 :
日本人? 

340 :
Androidのデータベースアプリについて
https://mevius.2ch.sc/test/read.cgi/db/1586288558/

341 :
UPSERTの逆みたいな処理をしたいです。
(挿入先テーブルにレコードが存在すればUPDATEし、挿入元データになければ、挿入先テーブルから削除する)
以下の挿入先マスタテーブルがあるとします。
-------------------------
|  id  |  name  |  age  |
-------------------------
|  1  |  Aさん  |   22  |
|  2  |  Bさん  |   20  |
|  3  |  Cさん  |   26  |
-------------------------
そして、以下の挿入元データで更新します。
-------------------------
|  id  |  name  |  age  |
-------------------------
|  2  |  Aさん  |   23  |
-------------------------
この時に、BさんとCさんのデータが消えてAさんのデータが上記のデータで更新されるようにしたいのですが、
どのようなクエリで出来ますでしょうか?
一回、マスタの全レコード削除して、挿入元レコード全てをINSERTし直すのも考えましたが、
データ量が多いのと、参照整合性制約を切ってINSERTしてまた制約を付け直す処理が必要になる為、
可能であればもっと簡単な方法を教えて下さい。

342 :
>>341
マスタテーブルをdropして
挿入テーブルをマスタテーブルにrenameする。

343 :
>>341
DELETEとINSERTの二発に分ける
・DBMSによってはDELETEでJOINが使える。
・使えなくてもWHEREでサブクエリを使えば同じことができる

344 :
>>341
DBMSがわからないので回答できないが
俺の使ってるDBMSなら2回になるけどDELETEとUPDATEで可能

345 :
データ量が多いならなおのこと、1レコードずつ処理される方法より
サクッと入れ替えた方が簡単そうだなぁ。

346 :
>>341
DBMSは?
(てか、質問ならテンプレ使え)

347 :
SQL ServerならMERGE一発で可

ソースに対象データがない場合のアクションはSQL標準のMERGEにはない機能なので
SQL標準のMERGEで対応したければ削除対象のキーを含む挿入元データを作成する

でもそんなんするくらいならテーブル入れ替えるかtruncate+select intoするほうが簡単
レプリしてればどの方法でも別途考慮は必要

348 :
>>341
削除したマスターのレコードを参照してるデータはどうなるの?
CASCADEでDELETE?

349 :
普通データ削除したい時は物理削除ではなく
削除用カラムを追加して削除フラグをたてるだけにする
データデースにはundo とかないので元に戻せないから
どうでもいいデータなら物理削除してもいいけどさ

350 :
外野で言うんだけどさ
マスターデータをこのようにさっくり消しているシステムって何か怖い

351 :
削除フラグは良し悪しあるからね
思考停止状態で削除フラグ入れてるところはDB設計がすぐ腐る

352 :
>>349
普通だと?

353 :
>>349
そういう論理削除が普通だと思っていると常に論理削除レコードかどうかを意識するSQLを書かないといけなくなり、テーブルにレコードがたまってしまう。

だから古いレコードは別テーブルに移動させる方がよい。

354 :
印字した帳票と連動してるので発番したものを戻せないとか
ユーザアカウントを一時凍結するとか
理由があれば、まあ

特に意味はないけどお客が安心するから
とりあえず論理削除方式ってのはありがち

んで、容量逼迫するから、月次や年次処理で
一定期間更新がない論理削除データを物理削除する
みたいなのもあったなぁ

355 :
ゆーて結局バックアップは別にとることが多いけどね

356 :
あと削除してもトランザクションログから戻せるよね

357 :
バックアップって、障害時の復旧には意味があるけれど
個別データの復活で使えるの?

358 :
例えば社員マスタで退社した社員を物理削除して削除した社員番号で違う人を登録した場合に不都合が生じる
退社した人のデータが連結されてしまうとかがある

359 :
>>342
その後の事(挿入テーブルはそのまま残す)を考えると

1.マスターテーブルをdrop&create(空テーブルで全件削除と同じ)
2.挿入テーブル全件をマスターテーブルにコピー

にした方がいいな。

360 :
>>358
それは設計のバグだろう。
もしかして自然に発生する障害みたいに思っているのかな。

361 :
このスレで言うのはなんだかそれ運用がおかしくないか?

362 :
>>361>>358

363 :
1から設計できる立場なら避けるけど
改修とかで押し付けられた既存システムキメラとかに
まれによくあるよね

364 :
社員マスタは例えばの話ですが
他のマスターでも起こりうる
論理削除だと永久欠番にできデータの整合性を保てるが物理削除すると前に使われていたかもわからなくなりデータ不整合が発生するリスクがあるんだと言いたかった。

365 :
自然キーじゃなくて得体のしれない「ID」を使ってるとみた。

366 :
はいはい別行ってやれ

367 :
まれによくある
ジョークのつもりなんだろか

368 :
>>358
それは社員番号の採番方式の問題やろ

369 :
下手なたとえをするとろくな事にならない

370 :
社員番号の再利用なんて聞いたことがないな。
俺が世間知らずなだけか?

371 :
>>370
過去に一度であったことがある
社員数が急増して、想定した桁数で足りなくなったという理由らしい
まあ、SQL関係ない

372 :
SQLの質問が入る

「そもそもその設計おかしくね?」とツッコミが入る

そのツッコミにまたツッコミが入る

設計談議で盛り上がる

373 :
バックアップなんて発想が出てくるのは、よほど小さいデータベースの話。

374 :
>>359
>その後の事(挿入テーブルはそのまま残す)を考えると

挿入テーブルを毎回新規作成すればよくね?
わざわざコピーする価値があるケースのほうが少ない気がするんだけど
古いマスターもdropじゃなくrenameすればアーカイブとして取っておける

375 :
質問者不在で盛り上がってるなw
>>349
普通とか書かない方がいいぞ
脳死で削除フラグつけるのはアンチパターンでもある
PK制約に明示的に名前つけてると
テーブル名リネームした時に変わらないでズレて悩むことがあるから注意な

376 :
>>373
え?

377 :
>>374
>挿入テーブルを毎回新規作成すればよくね?
そんな事を言い出したら質問の回答にならない。
質問者は処理後に挿入テーブルのデータを全てクリアするなんて
言ってないんだから。

378 :
テーブルを作るんじゃなくて、レコードを移動させろよ!

379 :
>>377
考え方が社畜の鑑やね

380 :
>>377
挿入テーブルのデータを残したいならそうすればいいだけ
コピーの有無以外にもマスターテーブルを先にdropするやり方は
挿入時にエラーが発生した場合の対処が複雑化するから一般的に悪手

381 :
>>380
それならまず別名でテーブルを作成し次に挿入テーブルから別名テーブルへの
コピーをしてエラーがなければマスタテーブルをdropして
別名をマスターにrenameすればいい。

社員情報のマスターはそれなりの件数があると思うし
処理サイクルは毎日か知らんが(多分毎日だろう)、処理する度に
わざわざDB上に旧データのバックアップテーブルを追加していくのは
どうかと思う。

バックアップならDB外のエクスポートファイル(ファイル名にYYYYMMDD等をつけて)
の圧縮で残せばいいと思う。

382 :
結局、毎回新規作成w
そんな事を言い出したら質問の回答にならないw

383 :
そろそろ模範解答とやらを出して、次の話題にしようぜ

384 :
>>381
社員マスタならむしろめちゃ件数少ないだろ

385 :
そろそろ別スレ行け

386 :
>>382
>結局、毎回新規作成w
何か問題でもあるのか?

>そんな事を言い出したら質問の回答にならないw
意味不明。
質問者の要求通りの回答をしてるつもりだけど。

387 :
消せるならDELETE(TRUNCATE)してカラムが全部同じならINSERTだろうが
制約があるから消せないって書いてないか?

388 :
そこは制約を一旦無効化してやるだろう。
ただ、再度有効化するのにかかる時間を考えたら UPDATE & DELETE と変わらんかもしれんが。

389 :
なんか勝手に処理追加しだしたぞw

390 :
追加された処理ってどれ?

391 :
>>381
単発処理ならいいけど定期処理ならまずやらない
バックアップが依存ジョブになるリスクや運用面への影響を全く考慮できてない

392 :
>>391
バックアップは一緒に処理しないで
バックアップ専用の処理(他のテーブルと合わせて)でいいと思う。

393 :
>>384
質問者(>>341)はデータ量が多いと言ってる。

しかし質問者は未だに返信なしかよw

394 :
設計スレの話題になるが
>>341
のデータで年齢ってあるけど普通は生年月日を定義して必要に応じて年齢を計算なんじゃないかと思うけど
年齢なんて定義するか?

395 :
>>394
>>341は項目としての例を挙げただけだと思う。
項目なんて何でもよかったんだよ。
キー項目があってキー項目でupdateしたいって事を
言いたかっただけだと思う。

396 :
単なるアンケートとかで普通にあるでしょ
アンケートごときに生年月日なんて言う個人情報を登録したくない人は多いだろうし

397 :
この話題、これ以上引っ張る意味あるのか?

398 :
よく見るとマスタに年齢もつのおかしいな
来年になったら更新が必要じゃん
生年月日もったほうがいいよな

399 :
ケースバイケース

400 :
死者マスタとか

401 :
お寺で使う法要データーベースかな

402 :
>>397
これはsqlのしつもんですか?

403 :
飽きたなら新しい話題振ればいいんじゃない?
「ボク、このはなしつまんなーい!」
ってガキじゃないんだから

404 :
少ないデータしか扱ったことがないやつは参考にならない。

405 :
それでは難しい質問をします
下記の複数レコードを1レコードにするSQLを教えて下さい
------------------
|  mail   |
------------------
|  aaa@hoge.com   |
|  bbb@hoge.com  |
|  ccc@hoge.com  |
-------------------
これをカンマ区切りで1レコードにする例は3件だが3件とは限らない
-------------------------------------------
|  mail    |
-------------------------------------------
|  aaa@hoge.com,bbb@hoge.com,ccc@hoge.com |
-------------------------------------------
データベースはSqlserverです

406 :
失職者の仕事できますアピールみたいだ

407 :
>>405
縦を横にするのは頻出の質問ではありますが標準的な方法はありません
その後の利用シーンによりますがSQL ServerならUDF書くのもありです

408 :
STRING_AGGでいいんでないの?
ttps://sql55.com/query/sql-server-2017-new-functions-string-agg.php

409 :
>>407
listagg()は標準(2016)に定義されている
同名の関数が定義されてなくてもgroup_concatやstring_aggのような同等の関数がある
めんどくさいからやらないけどCTEでも実現可
>>405
SQL Serverなら
1. STRING_AGG (2017)
2. COALESCE
3. FOR XML PATH
ただほとんどの場合SQLでやる必要ない

410 :
>>392
それバックアップ失敗してても困らない前提だよね?
renameはtransactionalに出来ないDBMSでもエラー検知して元に戻せるけど
dropはrollbackできないDBMSだと復旧モデルによってはデータロスト

411 :
>>393
そりゃ社員マスターじゃないからだろ

412 :
>>409
いろいろやり方おしえてくれてありがとうございました
COALESCEの場合は下記の様に変数使えばできるのですね知らなかった
DECLARE @STR VARCHAR(8000);
SELECT @STR = COALESCE(@STR + ’,’,’’) +[MAIL] 
FROM テーブル
SELECT @STR 

413 :
3件とは限らないってことはN件なんだから8000桁って指定しちゃだめだろ
アホ

414 :
>>413
アホはお前
https://docs.microsoft.com/ja-jp/sql/t-sql/data-types/char-and-varchar-transact-sql?view=sql-server-ver15

415 :
SQL Serverなら(max)とか別の制限かかる実質LOBな型もあるけど

元質問がSQL Serverだったから8000なんだが
このへんDBMSによってどのくらい違うんだろうな

416 :
VARCHARを問題にしてるんじゃないのか

417 :
>>416
どう問題なの?
MailがメールアドレスならANKしか入らないと思うが

418 :
max指定しろってことでしょ
ケースバイケースなので8000指定が駄目って事はない

419 :
>>418
> max指定しろってことでしょ
maxはオーバーヘッドあるからmaxならいいかどうかもケースバイケース

420 :
>>419
同じこと言い直してドヤるのやめて〜ww

421 :
左外部結合を使う というのを文にするときはどうしたいいですか?
Aを左、Bを右、xを共通として左外部結合する
みたいな言い方を考えていたのですが、正しい日本語の文があれば教えてください。

422 :
文章にすることで何を達成したいかっていう目的を書けよ

あらゆる状況に当てはまる万能な回答や
正しい回答があるという考えで通用するのは高校生まで

423 :
外部テーブル、内部テーブル、結合条件あたりが一般的な用語

(例)
Aを外部テーブル、Bを内部テーブル、A.x = B.xを結合条件として外部結合をする場合、
左外部結合なら外部テーブルを左に置いて`A LEFT OUTER JOIN B ON A.x = B.x`と書く
右外部結合なら…

424 :
>>423
左外部結合なら外部テーブルをJOIN句の左側に置いて…

425 :
ググったらこんなの見つけた
自然言語からSQL文を生成!リクルートのAI A3RT「SQL Suggest API」でクエリを作る
https://ledge.ai/a3rt-sqlsuggestapi/

426 :
>>422
目的は詳細設計書です。
コードは書けるのですが、日本語文にするとわかりづらく。

427 :
>>426
テーブル間の依存関係は文字だと表現しにくい
ER図がよく使われていると思う
https://it-koala.com/entity-relationship-diagram-1897

428 :
>>422 - >>427
助言ありがとうございます。
考えてみます。

429 :
>>427
ER図で表現できる内容ではないと思うぞ
図にするならベン図で色分けとかだろうけど
詳細設計書なら外部結合自体を知らない読み手を想定する必要はないだろうから
文章とSQLで十分だと思う

>>421
左や右はそんな重要な情報じゃないので
>>423のようにAが外部テーブル(外部表)だってことを明記するのがいいと思う

430 :
そもそも、左外部結合を使うじゃなくて
左外部結合する って書くのが普通じゃないのか

431 :
>>423
外部テーブル、内部テーブルという言い方は聞いたことがない。

結合方法なのにテーブルの種類みたいになっているのはおかしい。

外部表、内部表という言葉は俗語で、Oracle Databaseでは外部表はテーブルではないがテーブルとして扱えるファイルのことを差していたりもする。

432 :
>>426
それはSQLを直訳しようとしているからダメなんだよ。

どういうデータを取得したいのかを書こうとしていない。

433 :
>>430
それ本来は設計書じゃないよ。

434 :
>>426
詳細設計なら
別に日本語文章にしなくても
SQLそのまま書けばいいんじゃね?

何の為の詳細設計か知らんけど

435 :
>>431
outer table, inner tableの訳な、external tableとは別
お前が聞いたことなくても一般的に使われてるぞ
“join outer table”でoracleのリファレンスでもググってみれば

436 :
自然言語言語書き下し翻訳じゃなくて設計なんだから
「XXテーブルをxxコードで探索し存在するものについてはxxを取得する」
とかじゃないのか
建前としてそもそもSQL書く前の話なんだから

437 :
>>435
> お前が聞いたことなくても一般的に使われてるぞ
聞いたことないしググっても出てこん
お前がググった結果のURL貼ってくれ

438 :
>>437
435じゃないけど
日本語
https://www.google.com/search?q=%22%E5%A4%96%E9%83%A8%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB%22+%22%E5%86%85%E9%83%A8%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB%22+%28JOIN+OR+%E7%B5%90%E5%90%88%29
英語
https://www.google.com/search?q=%22inner+table%22+%22outer+table%22+join

連語とか漢字片仮名混じりをググる時はダブルクォートでくくるといいよ

439 :
>>437
site検索すればいいよ
https://www.google.com/search?q="outer+table"+site:docs.oracle.com
で見つかるのが例えばこれ↓
9.3.2 Outer Joins
In ANSI syntax, the OUTER JOIN clause specifies an outer join.
In the FROM clause, the left table appears to the left of the OUTER JOIN keywords, and the right table appears to the right of these keywords.
The left table is also called the outer table, and the right table is also called the inner table.
https://docs.oracle.com/en/database/oracle/oracle-database/18/tgsql/joins.html#GUID-2174C4BA-C852-4050-9269-353A3B40B355

440 :
>>435
だから日本語訳の話だと言っているだろ

441 :
>>439
inner、outerの意味がわかっているのか?

442 :
日本オラクルの翻訳を知らないとはあきれてる。

443 :
くるみぽんちおおおおおおおおおおおおおおおおおおおお

444 :
python3.6.8で作業しています。

ttps://datadryad.org/stash/dataset/doi:10.5061/dryad.8q0s4
この度上のデータベースを利用することになり、
sqlite3でreadmeにあるコマンドを順次実行したところ、
33行目で
sqlite3.OperationalError: near "LOAD": syntax error
と出てそこから先に進むことができません。
指すファイルは作業フォルダにあるはずなのですが、SQLは素人なこともあり、修正すべき場所がわかりません。
ご教授いただければ幸いです。

445 :
>>444
SQLiteにはLOAD DATAコマンドはないからな
.importコマンドでいけるかも
https://sfnovicenotes.blogspot.com/2019/10/sqlite3-tsvtsv.html

446 :
わざわざhを取っているあたりからネタだと思われる

447 :
SQL Server 2014です。
以下のようなテーブルがあって
記号 状態
A   0
A   0
B   0
B   1
B 0
C 0
C 1
記号「A」のような一つも状態「1」を持たない記号を知りたいのですがどのようなSQLで実現できるでしょうか?お願いします。

448 :
ずれたテーブルを投稿してしまい失礼しました。
記号 状態
A   0
A   0
B   0
B   1
B   0
C   0
C   1
状態の最大値が0の記号を出せばいけるかなと思いついたのですが
状態は文字列となっており断念しました。。。

449 :
普通にgroup by havingでいけない?

450 :
group by havingじゃいけなかったわ
not existsで
https://rextester.com/PTTTA8276

451 :
case式使えばいけなくもなかったわ
https://rextester.com/ESUVD85828

452 :
結構いろんな方法があるな
https://rextester.com/AACL20435

453 :
SQL-Serverなら文字列でもMax使えるから普通にgroup byとhavingでいけるでしょ
select 記号 from テーブル group by 記号 having max(状態) = '0'

454 :
やりたい事ができました
色々アドバイスありがとうございます
同じテーブルにNOT EXISTSとか思いもよりませんでした
大変参考になります

455 :
NOT EXISTSとGROUP BYどっちがパフォーマンスいいんだろ

456 :
実行計画次第だから、実際のテーブル定義と件数で実行計画比較しないと意味がない
NOT EXISTS(NOT INでも)だと自己結合するから、テーブルの走査が2回必要
HAVINGだと1回で済むので、こっちのほうが早いかもしれないし
インデックスで結合するテーブルの走査が圧倒的に早ければ結合するほうが早いかもしれない
普通のHAVINGにはインデックスきかないよね?
これをインデックス付きビューにしとけばおそらくそれが最速

457 :
2万件弱で試してみたが直感どおりの結果
https://rextester.com/TOMK9751

458 :
いまどきEXISTSにSELECT 1とか...

459 :
>>458
SQLに詳しいやつが
なんでSELECT 1使うのか調べたほうがいいよ

460 :
>>456
NOT INてインデックス有効?
NOT EXISTSの方が遥かに速かった記憶が。

461 :
ぐぐったら「SELECT 1の方が速い」「SELECT *の方が速い」「オラクルのバージョンによる」「評価されないのでどっちでもいい」ってマチマチだったので、試してみた
https://rextester.com/QWAU74067

462 :
>>460
NOT INの対象のサブクエリには当然効くでしょ

463 :
インデックスの話とは関係ないが
NOT IN使っても最近はオプティマイザがよろしくやってくれるから昔ほど避ける必要ない

464 :
phpmyadminをxamppで使用しています
特権タブにlocalhostがありますので、あらたにユーザーを追加しなくてもいいということでしょうか?localhost=自分ということかと思いますです

465 :
>>461
Oracle Databaseの慣習だと1ではなく、Xだけど、データを取得したいのか、データの有無を調べたいかの意志表示でこう書いている。

466 :
date player score movingAvg
20200502  A  90 ?

20200502  B  80 ?
20200502  C  95 ?
20200501  A  80 ?
20200501  B  75 ?
20200501  C  90 ?



という感じで、複数人のプレイヤーのスコアデータがあるときに、
各プレイヤーのスコアの移動平均を求めて別カラム(?のところ)
に保存する方法を教えてください。

スコアの移動平均は、その行の日付を含まないでその行の日付から
過去10日間のスコアの平均とします。

使っているのはsqlite3(python)です。

よろしくお願いします。

467 :
くそめんどくせーから日付の部分は自分で加工しろ
select date,player,score,(select avg(score) from tbl as tbl2 where tbl2.date<tbl.date and tbl2.date>=tbl.dateの10日前) from tbl

468 :
たぶんこんな感じ
日付周りは適当に直して
select
*,
(select avg(score) from scoretable
WHERE player=t.player and date < t.date and date >= (date - 10)
) AS ?
from scoretable t

469 :
歯抜けがなければwindow関数でもいけるけど
歯抜けがある場合にsqliteだとwindow関数でやるやり方わからないな
rowsじゃなくrange指定でdate関数使ったやり方分かる人いたら教えて
https://www.db-fiddle.com/f/wBESjSYhMTd9hTSWyDf9kE/0

470 :
>>467
>>468

ありがとうございます!
日付部分は、20200502→2020-05-02という形にして、
date(t.date, "-10 days")などとすればできました。

いただいたアドバイスを元に、

select * , (select avg(score) from scoreTable
WHERE player=t.player and date < t.date and date >= date(t.date, "-10 days"))
as movingAvg from scoreTable t

にて、*と計算されたmovingAvgを抜き出すことができました。
この結果をmovingAvgのカラムに保存したいのですが、
保存まで1つのsql文で書くにはどう書いたらよいでしょうか?
update scoreTable set movingAvg = (select …
のような感じで試みるもうまくいかず、、お願いします。

471 :
update scoreTable
set movingAvg = (select avg(t1.score) from scoreTable as t1 WHERE t1.player=scoreTable.player and t1.date < scoreTable.date and t1.date >= date(scoreTable.date, "-10 days"))

472 :
一応俺のくせなだけだが
別名をどちらかだけつけるなら加工する側のSQLにつけたほうがいいと思う

473 :
純粋に計算で求められる値をテーブルに保存すべきかどうかはよく検討したほうがいいぞ

474 :
>>471

ありがとうございます。そのままコピーしてできました!
教えていただいた皆様、大変ありがとうございました。

>>473
保存しないでメモリで計算すべきということでしょうか?
またあとでみたいので途中計算も保存しちゃってます。

475 :
全部質問で恥ずかしいのですが、もう1つお願いします。
移動平均の日付範囲の中に要素がなかったときに、
NOT NULL constraint failedというエラーとなります。
(当日を含まず、歯抜けの日もあるため)
avg()がNULLとなる場合をスキップしてそれ以外だけ
計算する方法がありましたら教えてください。

476 :
>>475
COALESCE

477 :
>>476

ありがとうございます。coalesceでぐぐって、
こちらのページをみて、
https://www.dbonline.jp/sqlite/function/index23.html

ひとまず、

update scoreTable set movingAvg =
ifnull((select avg(t1.score) from scoreTable as t1
WHERE t1.player=scoreTable.player and t1.date < scoreTable.date
and t1.date >= date(scoreTable.date, "-10 days")), 0.0)

としてみたらどうやらできました。

ありがとうございました。

478 :
>>469
ポスグレなら RANGE BETWEEN '10 day' PRECEDING とか書けるみたい
(https://masahikosawada.github.io/2018/07/07/Window-Frame/#fnref:syntax)
ちょっとSQL Serverでためしたけど、RANGEとか制約多すぎて使いもんにならんな

すなおに相関サブクエリでやるほうがいいパターンなんだろうかね

479 :
それNULLをスキップしてるんじゃなくてNULLをゼロにしてるだけなんだが...

ちゃんとスキップしたいならWHEREに条件かけよとか
そもそもなんでNOT NULLなんだとか
いやそもそもビューで良いんじゃねえかとか

つっこみどころ満載だな

480 :
プログラムに限らず、2ちゃんねるの専門系の質問スレって
どこよりもたよりになる。過去何度も助けられてる。
答えてる人々はどういうモチベーションなんだろう。
自己鍛錬的なあれだろうか。

481 :
そういえば最近自分も外れ値を除外するために移動平均をデータにセットしたな。しかしバラツキが大きいと移動平均と比較しても意味ないので標準偏差も計算してセットした。

482 :
まあ趣味的なデータっぽいからいいと思うが
自分もビューにしたほうがいいんじゃないかとは思う
日付のデータは当日分または前日分1日だけなら
毎回更新するのはコストがかかりすぎじゃないかという気もする

483 :
>>477
COALESCEはSQL標準
IFNULLやISNULLはDBMS特有の関数
なので都合が悪いケースじゃなければCOALESCE使う
よく読んでなかったけど
NOT NULL constraint failedって
moving_avgがnullになる可能性もあるのにNOT NULL付けたらだめじゃないの?
10日間のスコア平均が0.0の場合と値が無いケースとの区別ができなくなる

484 :
毎日1日分のデータを登録するという運用なら
INSERTするときにさっきのAVGのデータをSELECTでひろって
INSERT〜SELECTするという手もあるけどね

485 :
>>474
簡単に導出できる値を持つというのとは、二重、三重に値を持つことと同じことになる。

486 :
>>477
なんかどんどん変な慣習に引きずられているなw
他のひとも指摘しているけど、NULLを返すレコードがあるなら、そのレコードを初めから排除しとけよ。

487 :
皆様
ご指摘のとおり、自分でNOT NULLをつけており、
それがエラーになっていることがわかっていませんでした。
ビューというは知らないので調べてみます。
色々とご助言ありがとうございます。

488 :
>>477
自分のなかで決まりがなさすぎだろ。
なんとかdateという名前にしておきながら、データ型がバラバラとかあからさまに初心者。

489 :
ID:IGZUerYJ
なんだこいつw

490 :
あきらかに初心者な質問にそんな文句いってもなぁ
自分ではなにも回答してないのにマウントだけとりたいのか

なんかsqliteの解説みてると日付型ってもってなさそうだけど
データ型がバラバラってどこ見ていってるんだろうな

491 :
>>487
聞くのはいいけど
自分で試行錯誤した内容でアドバイスもらうのも
ありかと思うぜ

492 :
YYYYMMDDの書式が年月日だと思うのはエスパーなのかと思っただけ

493 :
SQLお悩み相談所w

494 :
分析能力がないのを言い訳にしてんなよ

495 :
1 http://i.imgur.com/CW4UUJe.jpg
2 http://images2.imgbox.com/39/cb/qYQo3EWi_o.jpg
3 http://i.imgur.com/3i00gxE.jpg
4 http://i.imgur.com/pp8F1bl.jpg
5 http://i.imgur.com/nCQ9UFR.jpg
6 http://i.imgur.com/LqmlgVI.jpg
7 http://i.imgur.com/JjGvnM1.jpg
8 http://i.imgur.com/uP3HCmf.jpg

496 :
ID | sub
--+----
1 | my
2 | name
3 | is
4 | john.
5 | your
6 | name
7 | is
8 | jane.

こういう、あるいみ文章みたいな文字列を
スペースごとにバラバラにされてレコード化されているテーブルを
ピリオドがある行までをまとめて

group | subs
-----+--------------------
1,2,3,4 | my name is john.
5,6,7,8 | your name is jane.

という風にグループ化して取得するにはどうしたらいいでしょうか。
環境はsqlite3です。場合によっては他DBに移行も考えています...

497 :
CTE使えばできそうだけど
そういうのはSQLじゃなくプログラム側で処理したほうが100倍簡単でメンテしやすいよ

498 :
こういう設計する人って何なんだろうな

499 :
こんな感じかな?
SELECT group_concat(ID,','),group_concat(sub,' ') FROM (
SELECT
a.ID,
MAX(a.sub) AS sub,
SUM(CASE WHEN b.sub LIKE '%.' THEN 1 ELSE 0 END) AS cnt
FROM test_table AS a
LEFT JOIN test_table AS b ON b.ID<a.ID
GROUP BY a.ID
ORDER BY a.ID
)
GROUP BY cnt;

500 :
O(n)でできるところをO(n^2)以上に悪化させてもSQLで処理する意味あるのかな

501 :
なんでもSQLでやろうとする人って保守とかはあまり考えてないよな
まあ俺が関係するわけじゃないからいいけど

502 :
ウィンドウ関数使ってみた
ttps://ideone.com/Zk56p2

503 :
>>502
嫌がらせかよっ!
てな気分になる

504 :
>>496
また同じようなネタw

505 :
独り言だけど、標準SQLが何でも取り入れてしまうから、もはや標準になってない。プロジェクトの規約にないことは人によって書き方がバラバラで疲れる。

506 :
sqlは広く使われてるlinterとかないからねー
formatterでさえ使って人少ない

507 :
oracleの(+)で外部結合お手軽すぎてこの書き方に慣れてしまった

508 :
体に毒だから、止めた方がいい

509 :
>>507
やめとけ

510 :
データベースSQLSERVERで教えて下さい

変数 @Aがあってnullだったらすべて対象でnull以外だったら
その値のみ更新とかwhere句でつけたいのですが

update テーブルA set カラZ = 1
where (カラムA = @A or @A is null)

とか考えたのですが他にもっとスマートな記述ありますでしょうか

511 :
(カラムA = @A or @A is null)はselectではよく使うパターン
条件が1つならif (@A IS NULL)のほうがいいかもしれないけど
たくさんあるならそのパターン使えば良いと思うよ
OPTION (RECOMPILE)を付けて各パターンで念の為プランを確認しておくこと

512 :
>>511
やはりorで記述するのが多いのですね。
ありがとうございました。

513 :
with句って今まであんまり使わなかったけどめちゃ便利じゃん
副問い合わせでごちゃごちゃネストするよりも可読性が高まる

514 :
PostgreSQL特有なのか他DBでも一般的なのか分からないけど
 column NOT LIKE '・・・・'
 column NOT IN (・・・・)
 column NOT BETWEEN a AND b
と演算子の前に「NOT」をつけてSQLを書いてもOKなのに
 column NOT ~ value
 column NOT = value
と演算子の前に「NOT」をつけて書くとエラーになるのって、どういう根拠によるものなのでしょう?

どっちも演算子なんだから前者の書き方で統一したいと思ったら出来なくて、
そもそもNOT演算子の意味を考えたら前者も「NOT column LIKE '・・・'」と書かないと
エラーになっちゃうんじゃ?とか考えだしたら何が正しい書き方なのか分からなくなっちゃった
SQLの正しい構文規則みたいな資料って、どれを見ればいいんでしょう?

515 :
SQL BNF でぐぐれ

516 :
>>514
NOT LIKEやNOT BETWEENのNOTとunary operatorのNOTは違うもの
INやLIKEのような一部の演算子についてだけ“NOT LIKE”が一つの演算子として働くイメージ
Postgres特有の話ではない

https://www.sqlite.org/lang_expr.html

517 :
あ、なるほど、>>516の説明で腑に落ちた
プログラミング言語でも「!=」が1つの演算子であり
「a△!△=△b」みたいに「!」「=」を分けて書けないのと同じ要領で、
SQLでも「NOT LIKE」なんかが1つの演算子に相当するということなんですね

BNFはちょっと理解できてないかもだけど、
「NOT」を書く場合の構文としてはLIKEみたいな述語の直前と決められてるってことなのかな

ひとつ賢くなれました、ありがとう

518 :
>「NOT」を書く場合の構文としてはLIKEみたいな述語の直前と決められてるってことなのかな
unary operator(単項演算子)のNOTのほうも別途存在してる

NOT column LIKE ‘foo%’ は NOT (expression)の形で単項演算子のNOT
column NOT LIKE ‘foo%’ は (expression) NOT LIKE (expression)の形で二項演算子的なもの

column NOT = valueは (= value)がexpressionじゃないから単項演算子として成立しない
(NOT =)という二項演算子もないので(expresison) NOT = (expression)も成立しない
IS NOTならあるので成立する

519 :
PL/sql(Postgres)で以下のようなテーブルの更新処理を実装したいです
fetchを入れ子するのではと思いますがいまいち実装サンプルなどが見つからずよく分かりません
例)テーブル(userID、 productID、price)があるとして
userIDごとにpriceから値引き額(別テーブルで定義)を引ききれるまで引く更新を全てのレコードに対して行いたいとしたら

userIDごとにレコードを取得?(ここでまずループ)
上で取得したuserIDごとのレコードをフェッチ(2つ目のループ)し、
該当レコードのpriceから値引き額を引けるだけ引いて更新
値引き額を、そのレコードで引いた金額を差し引いた余りに更新
のような計算イメージ

そもそもPL/SQLの書き方自体怪しいんですが上記のイメージで実装可能なのでしょうか

520 :
普通のsqlで出来るのでは?

521 :
確かにSQLだけでも出来るっぽい。
ttps://rextester.com/KMHR77477

522 :
SQLだけはめちゃくちゃ辛いな

そもそも注文明細的なテーブルの販売価格を直接更新して値引きする時点で設計に欠陥あるよね

523 :2020/06/09
>>521
サンプルコードまでありがとうございます
SQLでもできるんですね
アプリ側で実装できない事情があり頭抱えてたので、この線で一度レスポンスを見てみようと思います
設計自体の欠陥もご指摘の通りで、明細一つ一つを再計算する作り自体がよろしくないですね

(^^)BTRIEVE(^^)
DB設計を語るスレ 10
[終了]今は亡きInformixに文句を言うスレ[おつかれ]
SQL質疑応答スレ 18問目
【PostgreSQL CE認定試験】ってどう?
制約っていらなくね?
MySQL 総合 Part26
UNIX DBMはこちら(GNU gdbm, Berkeley DB etc...)
自治スレ@DB板 2
SELECT * に続けて何か書け!
--------------------
LA★ロサンゼルスへ行こう★LAX
中国のウイグル弾圧「憎悪生む」 100万人連行か、親族が訴え
3月は春でなく冬だ
【乞食速報】人生シミュレーションゲーム『The Sims 4』が無料配布中 [819960131]
もしも巨人が1996年にFAで清原を獲得しなかったら?
SATORU!!足利のヒーロー!!!
◆ROBOT魂 総合スレ 299体目◆
【経済】内閣府、GDP算出方法を変更 [田杉山脈★]
☆☆高学年の中学受験 Part86
ワタミン 「震えが来てうんち漏らすほど怖いのれすう」
【賄賂】山梨県の奥様【甲州選挙】36
【初心者】ゴルフ始める、最近始めた人のスレ★36
菊花賞が楽しみになってきたな
彼女がフラグをおられたら フラグ14本目
世界の☆★スパワールド★☆大温泉38
2ch初心者の時の書き込みを思い出して死ぬスレ
【悲報】山田涼介(25歳、身長164cm)と宮田聡子(29歳、身長170cm)が熱愛報道でジャニオタが大暴れ! [901679184]
埼玉県について知っていること★2
サガラとキヨトの乃木坂ぷぷぷ
☆★テレビ朝日 上宮菜々子 Parte14(^o^)y ☆☆
TOP カテ一覧 スレ一覧 100〜終まで 2ch元 削除依頼