sqlcompiler for linq(c#)のサンプル - sanki- · pdf fileno23.linq 1-4 having句の力...

63
SQLCompiler for LINQ(C#) のサンプル (応用サンプル) <一覧表> ファイル名 : 前版サンプルから更新したファイル名 ファイル名 節名 項目名 ページ リンク No2.linq 1-1 CASE 式のススメ 異なる条件の集計を1つの SQL で行う P14 の下の SQL 2 No5_2.linq 1-1 CASE 式のススメ テーブル同士のマッチング P21 の IN 述語 5_2 No6_2.linq 1-1 CASE 式のススメ テーブル同士のマッチング P21 の EXISTS 述語 6_2 No7.linq 1-1 CASE 式のススメ CASE 式の中で集約関数を使う P23 の最下部 SQL 7 No8.linq 1-1 CASE 式のススメ 演習問題 1-1 複数列の最大値(3 値) P27 8 No8_2.linq 1-1 CASE 式のススメ 演習問題 1-1 複数列の最大値(2 値) P27 8_2 No10.linq 1-2 自己結合の使い方 部分的に不一致なキーの検索 P35 10 No11.linq 1-2 自己結合の使い方 ランキング(同一順位があると連続しない) P37 の下の SQL 11 No12.linq 1-2 自己結合の使い方 ランキング(順位が連続する) P38 の 3 行目 12 No14.linq 1-4 HAVING 句の力 データの歯抜けを探す P65 14 No15.linq 1-4 HAVING 句の力 演習問題 4-1 常に結果を一行返す欠番チェック P80 15 No16.linq 1-4 HAVING 句の力 歯抜けの最小値を探す P67 16 No17.linq 1-4 HAVING 句の力 最頻値を求める P68 17 No18.linq 1-4 HAVING 句の力 最頻値を求める P69 18 No19.linq 1-4 HAVING 句の力 メジアンを求める P70 19 No20.linq 1-4 HAVING 句の力 NULL を含まない集合を探す P73 の上の SQL 20 No21.linq 1-4 HAVING 句の力 NULL を含まない集合を探す P73 の下の SQL 21 No22.linq 1-4 HAVING 句の力 演習問題 4-2 特性関数の練習 P80 22 1

Upload: phamthien

Post on 14-Mar-2018

217 views

Category:

Documents


3 download

TRANSCRIPT

SQLCompiler for LINQ(C#) のサンプル (応用サンプル)

<一覧表>

ファイル名 : 前版サンプルから更新したファイル名

ファイル名 節名 項目名 ページ リンク

No2.linq 1-1 CASE式のススメ 異なる条件の集計を1つのSQLで行う P14の下のSQL 表 2

No5_2.linq 1-1 CASE式のススメ テーブル同士のマッチング P21の IN述語 表 5_2

No6_2.linq 1-1 CASE式のススメ テーブル同士のマッチング P21の EXISTS述語 表 6_2

No7.linq 1-1 CASE式のススメ CASE式の中で集約関数を使う P23の最下部SQL 表 7

No8.linq 1-1 CASE式のススメ 演習問題1-1 複数列の最大値(3値) P27 表 8

No8_2.linq 1-1 CASE式のススメ 演習問題1-1 複数列の最大値(2値) P27 表 8_2

No10.linq 1-2 自己結合の使い方 部分的に不一致なキーの検索 P35 表 10

No11.linq 1-2 自己結合の使い方 ランキング(同一順位があると連続しない) P37の下のSQL 表 11

No12.linq 1-2 自己結合の使い方 ランキング(順位が連続する) P38の 3行目 表 12

No14.linq 1-4 HAVING句の力 データの歯抜けを探す P65 表 14

No15.linq 1-4 HAVING句の力 演習問題4-1 常に結果を一行返す欠番チェック P80 表 15

No16.linq 1-4 HAVING句の力 歯抜けの最小値を探す P67 表 16

No17.linq 1-4 HAVING句の力 最頻値を求める P68 表 17

No18.linq 1-4 HAVING句の力 最頻値を求める P69 表 18

No19.linq 1-4 HAVING句の力 メジアンを求める P70 表 19

No20.linq 1-4 HAVING句の力 NULLを含まない集合を探す P73の上のSQL 表 20

No21.linq 1-4 HAVING句の力 NULLを含まない集合を探す P73の下のSQL 表 21

No22.linq 1-4 HAVING句の力 演習問題4-2 特性関数の練習 P80 表 22

1

No23.linq 1-4 HAVING句の力 演習問題4-2 特性関数の練習 P80 表 23

No24_2.linq 1-5 外部結合の使い方 クロス表を作る P82 表 24_2

No26_2.linq 1-5 外部結合の使い方 クロス表を作る P84 表 26_2

No27_2.linq 1-5 外部結合の使い方 クロス表を作る P85 表 27_2

No28.linq 1-5 外部結合の使い方 掛け算として結合 P93 表 28

No29.linq 1-5 外部結合の使い方 掛け算として結合 P94 表 29

No35.linq 1-6 相関サブクエリで行と行を比較する 成長・後退・現状維持 P106の上のSQL 表 35

No36.linq 1-6 相関サブクエリで行と行を比較する 成長・後退・現状維持 P106の下のSQL 表 36

No37.linq 1-6 相関サブクエリで行と行を比較する 前年との比較結果を一覧表示する P107の上のSQL 表 37

No38.linq 1-6 相関サブクエリで行と行を比較する 前年との比較結果を一覧表示する P107の下のSQL 表 38

No39.linq 1-6 相関サブクエリで行と行を比較する 時系列に歯抜けがある場合:直近と比較 P109の 1つ目のSQL 表 39

No40.linq 1-6 相関サブクエリで行と行を比較する 時系列に歯抜けがある場合:直近と比較 P109の 2つ目のSQL 表 40

No41.linq 1-6 相関サブクエリで行と行を比較する 時系列に歯抜けがある場合:直近と比較 P109の 3つ目のSQL 表 41

No43.linq 1-6 相関サブクエリで行と行を比較する 移動累計と移動平均 P111の下のSQL 表 43

No44.linq 1-6 相関サブクエリで行と行を比較する 移動累計と移動平均 P113の下のSQL 表 44

No45.linq 1-6 相関サブクエリで行と行を比較する 移動累計と移動平均 P114の上のSQL 表 45

No46.linq 1-6 相関サブクエリで行と行を比較する オーバーラップする期間を調べる P117 表 46

No47.linq 1-7 SQLで集合演算 テーブル同士のコンペア P125 表 47

No48.linq 1-7 SQLで集合演算 等しい部分集合を見つける P134の上のSQL 表 48

No49.linq 1-8 EXISTS述語の使い方 テーブルに存在「しない」データを探す P146の上のSQL 表 49

No50.linq 1-8 EXISTS述語の使い方 テーブルに存在「しない」データを探す P146の下のSQL 表 50

No51.linq 1-8 EXISTS述語の使い方 肯定⇔二重否定の変換に慣れよう P147 表 51

No52.linq 1-8 EXISTS述語の使い方 肯定⇔二重否定の変換に慣れよう P149の上のSQL 表 52

No53.linq 1-8 EXISTS述語の使い方 肯定⇔二重否定の変換に慣れよう P149の下のSQL 表 53

No54.linq 1-8 EXISTS述語の使い方 演習問題8-1 配列テーブル-行待ちの場合 P156 表 54

2

No55.linq 1-8 EXISTS述語の使い方 演習問題8-1 配列テーブル-行待ちの場合 P156 表 55

No56.linq 1-8 EXISTS述語の使い方 演習問題8-1 配列テーブル-行待ちの場合 P156 表 56

No57.linq 1-8 EXISTS述語の使い方 演習問題8-1 配列テーブル-行待ちの場合 P156 表 57

No58.linq 1-8 EXISTS述語の使い方 演習問題8-3 素数を求める P157 表 58

No59.linq 1-9 SQLで数列を扱う 連番を作ろう P160 表 59

No60.linq 1-9 SQLで数列を扱う 連番を作ろう P161 表 60

No62.linq 1-9 SQLで数列を扱う 欠番を全部求める P163の 2つ目のSQL 表 62

No63_2.linq 1-9 SQLで数列を扱う 欠番を全部求める P163の 3つ目のSQL 表 63_2

No64.linq 1-9 SQLで数列を扱う 3人なんだけど、座れますか? P165 表 64

No65.linq 1-9 SQLで数列を扱う 最大何人まで座れますか? P169 表 65

No66.linq 1-9 SQLで数列を扱う 単調増加と単調減少 P172 表 66

No67.linq 1-9 SQLで数列を扱う 単調増加と単調減少 P173 表 67

No68.linq 1-9 SQLで数列を扱う 演習問題9-2 シーケンスを求める P175 表 68

No69.linq 1-9 SQLで数列を扱う 演習問題9-3 シーケンスを全て求める P175 表 69

No70.linq 1-10 帰ってきたHAVING句 各隊、総員点呼! P177 表 70

No71.linq 1-10 帰ってきたHAVING句 各隊、総員点呼! P178 表 71

No72.linq 1-10 帰ってきたHAVING句 一意集合と多集合 P182の上のSQL 表 72

No73.linq 1-10 帰ってきたHAVING句 一意集合と多集合 P182の下のSQL 表 73

No74.linq 1-10 帰ってきたHAVING句 一意集合と多集合 P183 表 74

No75.linq 1-10 帰ってきたHAVING句 欠番を探せ:発展版 P185の 1つ目のSQL 表 75

No76.linq 1-10 帰ってきたHAVING句 欠番を探せ:発展版 P185の 2つ目のSQL 表 76

No77.linq 1-10 帰ってきたHAVING句 欠番を探せ:発展版 P185の 3つ目のSQL 表 77

No78.linq 1-10 帰ってきたHAVING句 集合にきめ細やかな条件を設定する P187の上のSQL 表 78

No79.linq 1-10 帰ってきたHAVING句 集合にきめ細やかな条件を設定する P187の下のSQL 表 79

No80.linq 1-10 帰ってきたHAVING句 集合にきめ細やかな条件を設定する P188 表 80

3

No80_2.linq 1-10 帰ってきたHAVING句 集合にきめ細やかな条件を設定する P189 表 80_2

TopPage

ファイル名 No2.linq

節名 1-1 CASE式のススメ

項目名 異なる条件の集計を1つのSQLで行う

ページ P14の下のSQL

T-SQL SELECT pub_id,

SUM(CASE WHEN type = 'business' THEN price ELSE 0 END) AS business

, SUM(CASE WHEN type = 'psychology' THEN price ELSE 0 END) AS psychology

, SUM(CASE WHEN type = 'mod_cook' THEN price ELSE 0 END) AS mod_cook

, SUM(CASE WHEN type = 'trad_cook' THEN price ELSE 0 END) AS trad_cook

, SUM(CASE WHEN type = 'popular_comp' THEN price ELSE 0 END) AS popular_comp

, SUM(CASE WHEN type = 'UNDECIDED' THEN price ELSE 0 END) AS undecided

FROM titles

GROUP BY pub_id

LINQコード titles

.GroupBy(x1 => new {grKey1 = x1.pub_id})

.Select(g1 => new

{

pub_id = g1.Key.grKey1,

business = g1.Sum(x1 => (x1.type == "business" ? x1.price : (int?)(0))),

psychology = g1.Sum(x1 => (x1.type == "psychology" ? x1.price : (int?)(0))),

mod_cook = g1.Sum(x1 => (x1.type == "mod_cook" ? x1.price : (int?)(0))),

trad_cook = g1.Sum(x1 => (x1.type == "trad_cook" ? x1.price : (int?)(0))),

popular_comp = g1.Sum(x1 => (x1.type == "popular_comp" ? x1.price : (int?)(0))),

undecided = g1.Sum(x1 => (x1.type == "UNDECIDED" ? x1.price : (int?)(0)))

});

TopPage

4

ファイル名 No5_2.linq

節名 1-1 CASE式のススメ

項目名 テーブル同士のマッチング

ページ P21の IN述語

T-SQL SELECT pub_name,

CASE WHEN pub_id IN

(SELECT pub_id FROM titles

WHERE pubdate BETWEEN '1991-06-01' AND '1991-06-30')

THEN '○'

ELSE '×' END AS Y1991M06,

CASE WHEN pub_id IN

(SELECT pub_id FROM titles

WHERE pubdate BETWEEN '1991-10-01' AND '1991-10-31')

THEN '○'

ELSE '×' END AS Y1991M10,

CASE WHEN pub_id IN

(SELECT pub_id FROM titles

WHERE pubdate BETWEEN '1994-06-01' AND '1994-06-30')

THEN '○'

ELSE '×' END AS Y1994M06,

CASE WHEN pub_id IN

(SELECT pub_id FROM titles

WHERE pubdate BETWEEN '2009-08-01' AND '2009-08-31')

THEN '○'

ELSE '×' END AS Y2009M08

FROM publishers

LINQコード publishers

.Select(x1 => new

{

x1.pub_name,

Y1991M06 = (titles

5

.Where(x2 => x2.pubdate >= DateTime.Parse("1991-06-01") && x2.pubdate <= DateTime.Parse("1991-06-30"))

.Select(x2 => new

{

x2.pub_id

}).Any(t => x1.pub_id == t.pub_id) ? "○" : "×"),

Y1991M10 = (titles

.Where(x3 => x3.pubdate >= DateTime.Parse("1991-10-01") && x3.pubdate <= DateTime.Parse("1991-10-31"))

.Select(x3 => new

{

x3.pub_id

}).Any(t => x1.pub_id == t.pub_id) ? "○" : "×"),

Y1994M06 = (titles

.Where(x4 => x4.pubdate >= DateTime.Parse("1994-06-01") && x4.pubdate <= DateTime.Parse("1994-06-30"))

.Select(x4 => new

{

x4.pub_id

}).Any(t => x1.pub_id == t.pub_id) ? "○" : "×"),

Y2009M08 = (titles

.Where(x5 => x5.pubdate >= DateTime.Parse("2009-08-01") && x5.pubdate <= DateTime.Parse("2009-08-31"))

.Select(x5 => new

{

x5.pub_id

}).Any(t => x1.pub_id == t.pub_id) ? "○" : "×")

});

TopPage

ファイル名 No6_2.linq

節名 1-1 CASE式のススメ

項目名 テーブル同士のマッチング

ページ P21の EXISTS述語

T-SQL SELECT PUB.pub_name,

6

CASE WHEN EXISTS

(SELECT pub_id FROM titles AS TIT

WHERE pubdate BETWEEN '1991-06-01' AND '1991-06-30'

AND TIT.pub_id = PUB.pub_id)

THEN '○'

ELSE '×' END AS Y1991M06,

CASE WHEN EXISTS

(SELECT pub_id FROM titles AS TIT

WHERE pubdate BETWEEN '1991-10-01' AND '1991-10-31'

AND TIT.pub_id = PUB.pub_id)

THEN '○'

ELSE '×' END AS Y1991M10,

CASE WHEN EXISTS

(SELECT pub_id FROM titles AS TIT

WHERE pubdate BETWEEN '1994-06-01' AND '1994-06-30'

AND TIT.pub_id = PUB.pub_id)

THEN '○'

ELSE '×' END AS Y1994M06,

CASE WHEN EXISTS

(SELECT pub_id FROM titles AS TIT

WHERE pubdate BETWEEN '2009-08-01' AND '2009-08-31'

AND TIT.pub_id = PUB.pub_id)

THEN '○'

ELSE '×' END AS Y2009M08

FROM publishers AS PUB

LINQコード publishers

.Select(x1 => new

{

x1.pub_name,

Y1991M06 = (titles.Any(x2 => x2.pubdate >= DateTime.Parse("1991-06-01") && x2.pubdate <= DateTime.Parse("1991-06-30")

&& x2.pub_id == x1.pub_id) ? "○" : "×"),

Y1991M10 = (titles.Any(x3 => x3.pubdate >= DateTime.Parse("1991-10-01") && x3.pubdate <= DateTime.Parse("1991-10-31")

&& x3.pub_id == x1.pub_id) ? "○" : "×"),

Y1994M06 = (titles.Any(x4 => x4.pubdate >= DateTime.Parse("1994-06-01") && x4.pubdate <= DateTime.Parse("1994-06-30")

7

&& x4.pub_id == x1.pub_id) ? "○" : "×"),

Y2009M08 = (titles.Any(x5 => x5.pubdate >= DateTime.Parse("2009-08-01") && x5.pubdate <= DateTime.Parse("2009-08-31")

&& x5.pub_id == x1.pub_id) ? "○" : "×")

});

TopPage

ファイル名 No7.linq

節名 1-1 CASE式のススメ

項目名 CASE式の中で集約関数を使う

ページ P23の最下部のSQL

T-SQL SELECT au_id, CASE WHEN COUNT(*) = 1 THEN MAX(title_id)

ELSE MAX(CASE WHEN au_ord = 2 THEN title_id ELSE 'Another' END)

END AS main_title_id

FROM titleauthor

GROUP BY au_id

LINQコード titleauthors

.GroupBy(x1 => new{grKey1 = x1.au_id})

.Select(g1 => new

{

au_id = g1.Key.grKey1,

main_title_id = (g1.Count() == 1 ? g1.Max(x1 => x1.title_id) : g1.Max(x1 => (x1.au_ord == 2 ? x1.title_id :

"Another")))

});

TopPage

ファイル名 No8.linq

節名 1-1 CASE式のススメ

項目名 演習問題1-1 複数列の最大値(3値)

8

ページ P27

T-SQL SELECT title_id, CASE WHEN CASE WHEN price < advance

THEN advance

ELSE price END < royalty

THEN royalty

ELSE CASE WHEN price < advance

THEN advance

ELSE price END

END AS greatest

FROM titles

LINQコード titles

.Select(x1 => new

{

x1.title_id,

greatest = ((x1.price < x1.advance ? x1.advance : x1.price) < x1.royalty ? x1.royalty : (x1.price < x1.advance ?

x1.advance : x1.price))

});

TopPage

ファイル名 N08_2.linq

節名 1-1 CASE式のススメ

項目名 演習問題1-1 複数列の最大値(2値)

ページ P27

T-SQL SELECT title_id, CASE WHEN price < advance

THEN advance

ELSE price END AS greatest

FROM titles

LINQコード titles

.Select(x1 => new

{

9

x1.title_id,

greatest = (x1.price < x1.advance ? x1.advance : x1.price)

});

TopPage

ファイル名 No10.linq

節名 1-2 自己結合の使い方

項目名 部分的に不一致なキーの検索

ページ P35

T-SQL SELECT DISTINCT t1.title_id, t1.price

FROM titles AS t1, titles AS t2

WHERE t1.price = t2.price

AND t1.title_id <> t2.title_id

ORDER BY t1.price

LINQコード titles

.SelectMany(t2 => titles,

(t1, t2) => new{t1, t2})

.Where(x1 => x1.t1.price == x1.t2.price && x1.t1.title_id != x1.t2.title_id)

.Select(x1 => new

{

x1.t1.title_id,

x1.t1.price

})

.Distinct()

.OrderBy(t => t.price);

TopPage

ファイル名 No11.linq

10

節名 1-2 自己結合の使い方

項目名 ランキング(同一順位があると連続しない)

ページ P37の下のSQL

T-SQL SELECT t1.title_id, t1.price,

(SELECT COUNT(t2.price)

FROM titles AS t2

WHERE t2.price > t1.price) + 1 AS rank

FROM titles AS t1

ORDER BY rank

LINQコード titles

.Select(x1 => new

{

x1.title_id,

x1.price,

rank = titles

.Where(x2 => x2.price > x1.price).Count(x2 => x2.price != null) + 1

})

.OrderBy(t => t.rank);

TopPage

ファイル名 No12.linq

節名 1-2 自己結合の使い方

項目名 ランキング(順位が連続する)

ページ P38の 3行目

T-SQL SELECT t1.title_id, t1.price,

(SELECT COUNT(DISTINCT t2.price)

FROM titles AS t2

WHERE t2.price > t1.price) + 1 AS rank

FROM titles AS t1

11

order by rank

LINQコード titles

.Select(x1 => new

{

x1.title_id,

x1.price,

rank = titles

.Where(x2 => x2.price > x1.price).Where(x2 => x2.price != null).Select(x2 =>

x2.price).Distinct().Count() + 1

})

.OrderBy(t => t.rank);

TopPage

ファイル名 No14.linq

節名 1-4 HAVING句の力

項目名 データの歯抜けを探す

ページ P65

T-SQL SELECT '歯抜けあり' AS gap

FROM jobs

HAVING COUNT(*) <> MAX(job_id)

LINQコード jobs

.Where(x1 => jobs.Count() != jobs.Max(x3 => x3.job_id))

.Select(x1 => new

{

gap = "歯抜けあり"

})

.Distinct();

TopPage

12

ファイル名 No15.linq

節名 1-4 HAVING句の力

項目名 演習問題4-1 常に結果を一行返す欠番チェック

ページ P80

T-SQL SELECT CASE WHEN COUNT(*) <> MAX(job_id) THEN '歯抜けあり'

ELSE '歯抜けなし' END AS gap

FROM jobs

LINQコード jobs

.Select(x1 => new

{

gap = (jobs.Count() != jobs.Max(x3 => x3.job_id) ? "歯抜けあり" : "歯抜けなし")

})

.Distinct();

TopPage

ファイル名 No16.linq

節名 1-4 HAVING句の力

項目名 歯抜けの最小値を探す

ページ P67

T-SQL SELECT MIN(job_id + 1) AS gap

FROM employee

WHERE (job_id + 1) NOT IN (SELECT job_id FROM employee)

LINQコード employees

.Select(x1 => new

{

gap = employees

.Where(x2 => employees

.Select(x3 => new

13

{

x3.job_id

}).All(t => (x2.job_id + 1) != t.job_id)).Min(x2 => x2.job_id + 1)

})

.Distinct();

TopPage

ファイル名 N017.linq

節名 1-4 HAVING句の力

項目名 最頻値を求める

ページ P68

T-SQL SELECT job_id, COUNT(*) AS cnt

FROM employee

GROUP BY job_id

HAVING COUNT(*) >= ALL(SELECT COUNT(*)

FROM employee

GROUP BY job_id)

LINQコード employees

.GroupBy(x1 => new{grKey1 = x1.job_id})

.Where(g1 => employees

.GroupBy(x2 => new{grKey2 = x2.job_id})

.Select(g2 => new

{

res1 = g2.Count()

}).All(t => g1.Count() >= t.res1))

.Select(g1 => new

{

job_id = g1.Key.grKey1,

cnt = g1.Count()

});

14

TopPage

ファイル名 No18.linq

節名 1-4 HAVING句の力

項目名 最頻値を求める

ページ P69

T-SQL SELECT job_id, COUNT(*) AS cnt

FROM employee

GROUP BY job_id

HAVING COUNT(*) >= (SELECT MAX(cnt)

FROM (SELECT COUNT(*) AS cnt

FROM employee

GROUP BY job_id) TMP)

LINQコード employees

.GroupBy(x1 => new{grKey1 = x1.job_id})

.Where(g1 => g1.Count() >= employees

.GroupBy(x3 => new{grKey2 = x3.job_id})

.Select(g2 => new

{

cnt = g2.Count()

}).Max(x2 => x2.cnt))

.Select(g1 => new

{

job_id = g1.Key.grKey1,

cnt = g1.Count()

});

TopPage

ファイル名 No19.linq

15

節名 1-4 HAVING句の力

項目名 メジアンを求める

ページ P70

T-SQL SELECT AVG(DISTINCT min_lvl)

FROM (SELECT t1.min_lvl

FROM jobs AS t1, jobs AS t2

GROUP BY t1.min_lvl

HAVING SUM(CASE WHEN t2.min_lvl >= t1.min_lvl

THEN 1 ELSE 0 END) >= COUNT(*) / 2

AND SUM(CASE WHEN t2.min_lvl <= t1.min_lvl

THEN 1 ELSE 0 END) >= COUNT(*) / 2) tmp

LINQコード jobs

.SelectMany(t2 => jobs,

(t1, t2) => new {t1, t2})

.GroupBy(x2 => new {grKey1 = x2.t1.min_lvl})

.Where(g1 => g1.Sum(x2 => (int?)((x2.t2.min_lvl >= g1.Key.grKey1 ? 1 : 0))) >= g1.Count() / 2 &&

g1.Sum(x2 => (int?)((x2.t2.min_lvl <= g1.Key.grKey1 ? 1 : 0))) >= g1.Count() / 2)

.Select(g1 => new

{

min_lvl = g1.Key.grKey1

})

.Select(x1 => new

{

root_alias_1 = jobs

.SelectMany(t2 => jobs,

(t1, t2) => new {t1, t2})

.GroupBy(x4 => new {grKey2 = x4.t1.min_lvl})

.Where(g2 => g2.Sum(x4 => (int?)((x4.t2.min_lvl >= g2.Key.grKey2 ? 1 : 0))) >= g2.Count() / 2 &&

g2.Sum(x4 => (int?)((x4.t2.min_lvl <= g2.Key.grKey2 ? 1 : 0))) >= g2.Count() / 2)

.Select(g2 => new

{

min_lvl = g2.Key.grKey2

}).Select(x3 => (int?)(x3.min_lvl)).Distinct().Average()

})

16

.Distinct();

TopPage

ファイル名 No20.linq

節名 1-4 HAVING句の力

項目名 NULLを含まない集合を探す

ページ P73の上のSQL

T-SQL SELECT type

FROM titles

GROUP BY type

HAVING COUNT(*) = COUNT(price)

LINQコード titles

.GroupBy(x1 => new{grKey1 = x1.type})

.Where(g1 => g1.Count() == g1.Count(x1 => x1.price != null))

.Select(g1 => new

{

type = g1.Key.grKey1

});

TopPage

ファイル名 No21.linq

節名 1-4 HAVING句の力

項目名 NULLを含まない集合を探す

ページ P73の下のSQL

T-SQL SELECT type

FROM titles

GROUP BY type

17

HAVING COUNT(*) = SUM(CASE WHEN price IS NOT NULL

THEN 1 ELSE 0 END)

LINQコード titles

.GroupBy(x1 => new {grKey1 = x1.type})

.Where(g1 => g1.Count() == g1.Sum(x1 => (int?)((!(x1.price == null) ? 1 : 0))))

.Select(g1 => new

{

type = g1.Key.grKey1

});

TopPage

ファイル名 No22.linq

節名 1-4 HAVING句の力

項目名 演習問題4-2 特性関数の練習

ページ P80

T-SQL SELECT type

FROM titles

GROUP BY type

HAVING COUNT(*) = SUM(CASE WHEN price IS NOT NULL

AND pubdate BETWEEN '1991-06-01' AND '1991-06-30'

THEN 1 ELSE 0 END)

LINQコード titles

.GroupBy(x1 => new {grKey1 = x1.type})

.Where(g1 => g1.Count() == g1.Sum(x1 => (int?)((!(x1.price == null) && x1.pubdate >=

DateTime.Parse("1991-06-01") && x1.pubdate <= DateTime.Parse("1991-06-30") ? 1 : 0))))

.Select(g1 => new

{

type = g1.Key.grKey1

});

18

TopPage

ファイル名 No23.linq

節名 1-4 HAVING句の力

項目名 演習問題4-2 特性関数の練習

ページ P80

T-SQL SELECT type

FROM titles

GROUP BY type

HAVING COUNT(*) = SUM(CASE WHEN price IS NOT NULL

AND DATEPART(yyyy, pubdate) = 1991

AND DATEPART(mm, pubdate) = 06

THEN 1 ELSE 0 END)

LINQコード titles

.GroupBy(x1 => new {grKey1 = x1.type})

.Where(g1 => g1.Count() == g1.Sum(x1 => (int?)((!(x1.price == null) && (x1.pubdate).Year == 1991 &&

(x1.pubdate).Month == 06 ? 1 : 0))))

.Select(g1 => new

{

type = g1.Key.grKey1

});

TopPage

ファイル名 No24_2.linq

節名 1-5 外部結合の使い方

項目名 クロス表を作る

ページ P82

T-SQL SELECT c0.stor_id,

CASE WHEN c1.stor_id IS NOT NULL THEN '○' ELSE '' END AS STATE_WA,

19

CASE WHEN c2.stor_id IS NOT NULL THEN '○' ELSE '' END AS STATE_CA,

CASE WHEN c3.stor_id IS NOT NULL THEN '○' ELSE '' END AS STATE_OR

FROM (SELECT stor_id FROM stores) c0

LEFT OUTER JOIN (SELECT stor_id FROM stores WHERE state = 'WA') c1

ON c0.stor_id = c1.stor_id

LEFT OUTER JOIN (SELECT stor_id FROM stores WHERE state = 'CA') c2

ON c0.stor_id = c2.stor_id

LEFT OUTER JOIN (SELECT stor_id FROM stores WHERE state = 'OR') c3

ON c0.stor_id = c3.stor_id

LINQコード stores

.Select(x2 => new

{

x2.stor_id

})

.GroupJoin(stores

.Where(x3 => x3.state == "WA")

.Select(x3 => new

{

x3.stor_id

}),

c0 => c0.stor_id,

c1 => c1.stor_id,

(c0, ig1) => new{c0, ig1})

.SelectMany(gj => gj.ig1.DefaultIfEmpty(),

(o1, i1) => new{o1, i1})

.GroupJoin(stores

.Where(x5 => x5.state == "CA")

.Select(x5 => new

{

x5.stor_id

}),

x1 => x1.o1.c0.stor_id,

c2 => c2.stor_id,

(x1, ig2) => new{x1, ig2})

20

.SelectMany(gj => gj.ig2.DefaultIfEmpty(),

(o2, i2) => new{o2, i2})

.GroupJoin(stores

.Where(x7 => x7.state == "OR")

.Select(x7 => new

{

x7.stor_id

}),

x4 => x4.o2.x1.o1.c0.stor_id,

c3 => c3.stor_id,

(x4, ig3) => new{x4, ig3})

.SelectMany(gj => gj.ig3.DefaultIfEmpty(),

(o3, i3) => new{o3, i3})

.Select(x6 => new

{

x6.o3.x4.o2.x1.o1.c0.stor_id,

STATE_WA = (!((x6.o3.x4.o2.x1.i1 != null ? x6.o3.x4.o2.x1.i1.stor_id : null) == null) ? "○" : ""),

STATE_CA = (!((x6.o3.x4.i2 != null ? x6.o3.x4.i2.stor_id : null) == null) ? "○" : ""),

STATE_OR = (!((x6.i3 != null ? x6.i3.stor_id : null) == null) ? "○" : "")

});

TopPage

ファイル名 No26_2.linq

節名 1-5 外部結合の使い方

項目名 クロス表を作る

ページ P84

T-SQL SELECT c0.stor_id,

(SELECT '○'

FROM stores AS c1

WHERE state = 'WA'

21

AND c1.stor_id = c0.stor_id) AS STATE_WA,

(SELECT '○'

FROM stores AS c2

WHERE state = 'CA'

AND c2.stor_id = c0.stor_id) AS STATE_CA,

(SELECT '○'

FROM stores AS c3

WHERE state = 'OR'

AND c3.stor_id = c0.stor_id) AS STATE_OR

FROM (SELECT stor_id FROM stores) c0

LINQコード stores

.Select(x2 => new

{

x2.stor_id

})

.Select(x1 => new

{

x1.stor_id,

STATE_WA = stores

.Where(x3 => x3.state == "WA" && x3.stor_id == x1.stor_id)

.Select(x3 => "○").SingleOrDefault(),

STATE_CA = stores

.Where(x4 => x4.state == "CA" && x4.stor_id == x1.stor_id)

.Select(x4 => "○").SingleOrDefault(),

STATE_OR = stores

.Where(x5 => x5.state == "OR" && x5.stor_id == x1.stor_id)

.Select(x5 => "○").SingleOrDefault()

});

TopPage

ファイル名 No27_2.linq

節名 1-5 外部結合の使い方

22

項目名 クロス表を作る

ページ P85

T-SQL SELECT stor_id,

CASE WHEN SUM(CASE WHEN state = 'WA' THEN 1 ELSE NULL END) = 1

THEN '○' ELSE NULL END AS STATE_WA,

CASE WHEN SUM(CASE WHEN state = 'CA' THEN 1 ELSE NULL END) = 1

THEN '○' ELSE NULL END AS STATE_CA,

CASE WHEN SUM(CASE WHEN state = 'OR' THEN 1 ELSE NULL END) = 1

THEN '○' ELSE NULL END AS STATE_OR

FROM stores

GROUP BY stor_id

LINQコード stores

.GroupBy(x1 => new{grKey1 = x1.stor_id})

.Select(g1 => new

{

stor_id = g1.Key.grKey1,

STATE_WA = (g1.Sum(x1 => (x1.state == "WA" ? (int?)(1) : null)) == 1 ? "○" : null),

STATE_CA = (g1.Sum(x1 => (x1.state == "CA" ? (int?)(1) : null)) == 1 ? "○" : null),

STATE_OR = (g1.Sum(x1 => (x1.state == "OR" ? (int?)(1) : null)) == 1 ? "○" : null)

});

TopPage

ファイル名 No28.linq

節名 1-5 外部結合の使い方

項目名 掛け算として結合

ページ P93

T-SQL SELECT p.pub_id, t.total_price

FROM publishers AS p LEFT OUTER JOIN

(SELECT pub_id, SUM(price) AS total_price

FROM titles

23

GROUP BY pub_id) AS t

ON p.pub_id = t.pub_id

LINQコード publishers

.GroupJoin(titles

.GroupBy(x2 => new{grKey1 = x2.pub_id})

.Select(g1 => new

{

pub_id = g1.Key.grKey1,

total_price = g1.Sum(x2 => x2.price)

}),

p => p.pub_id,

t => t.pub_id,

(p, ig1) => new{p, ig1})

.SelectMany(gj => gj.ig1.DefaultIfEmpty(),

(o1, i1) => new{o1, i1})

.Select(x1 => new

{

x1.o1.p.pub_id,

total_price = (x1.i1 != null ? x1.i1.total_price : null)

});

TopPage

ファイル名 No29.linq

節名 1-5 外部結合の使い方

項目名 掛け算として結合

ページ P94

T-SQL SELECT p.pub_id, SUM(t.price) AS total_price

FROM publishers AS p LEFT OUTER JOIN titles AS t

ON p.pub_id = t.pub_id

GROUP BY p.pub_id

24

LINQコード publishers

.GroupJoin(titles,

p => p.pub_id,

t => t.pub_id,

(p, ig1) => new{p, ig1})

.SelectMany(gj => gj.ig1.DefaultIfEmpty(),

(o1, i1) => new{o1, i1})

.GroupBy(x1 => new{grKey1 = x1.o1.p.pub_id})

.Select(g1 => new

{

pub_id = g1.Key.grKey1,

total_price = g1.Sum(x1 => (x1.i1 != null ? x1.i1.price : null))

});

TopPage

ファイル名 No35.linq

節名 1-6 相関サブクエリで行と行を比較する

項目名 成長・後退・現状維持

ページ P106の上のSQL

T-SQL SELECT job_id, min_lvl

FROM jobs AS J1

WHERE min_lvl = ( SELECT min_lvl

FROM jobs AS J2

WHERE J2.job_id = J1.job_id - 1)

ORDER BY job_id

LINQコード jobs

.Where(x1 => jobs

.Where(x2 => x2.job_id == x1.job_id - 1)

.Select(x2 => new

{

25

x2.min_lvl

}).Any(t => x1.min_lvl == t.min_lvl))

.Select(x1 => new

{

x1.job_id,

x1.min_lvl

})

.OrderBy(t => t.job_id);

TopPage

ファイル名 No36.linq

節名 1-6 相関サブクエリで行と行を比較する

項目名 成長・後退・現状維持

ページ P106の下のSQL

T-SQL SELECT J1.job_id, J1.min_lvl

FROM jobs AS J1, jobs AS J2

WHERE J1.min_lvl = j2.min_lvl

AND J2.job_id = J1.job_id - 1

ORDER BY j1.job_id

LINQコード jobs

.SelectMany(J2 => jobs,

(J1, J2) => new{J1, J2})

.Where(x1 => x1.J1.min_lvl == x1.J2.min_lvl && x1.J2.job_id == x1.J1.job_id - 1)

.Select(x1 => new

{

x1.J1.job_id,

x1.J1.min_lvl

})

.OrderBy(t => t.job_id);

26

TopPage

ファイル名 No37.linq

節名 1-6 相関サブクエリで行と行を比較する

項目名 前年との比較結果を一覧表示する

ページ P107の上のSQL

T-SQL SELECT j1.job_id, j1.min_lvl,

CASE WHEN min_lvl =

( SELECT min_lvl

FROM jobs AS j2

WHERE j2.job_id = j1.job_id - 1) then '→'

WHEN min_lvl >

( SELECT min_lvl

FROM jobs AS j2

WHERE j2.job_id =j1.job_id - 1) then '↑'

WHEN min_lvl <

( SELECT min_lvl

FROM jobs AS j2

WHERE j2.job_id = j1.job_id - 1) then '↓'

ELSE '-' END AS var

FROM jobs AS j1

ORDER BY job_id

LINQコード jobs

.Select(x1 => new

{

x1.job_id,

x1.min_lvl,

var = (jobs

.Where(x2 => x2.job_id == x1.job_id - 1)

.Select(x2 => new

{

x2.min_lvl

27

}).Any(t => x1.min_lvl == t.min_lvl) ? "→" :

jobs

.Where(x3 => x3.job_id == x1.job_id - 1)

.Select(x3 => new

{

x3.min_lvl

}).Any(t => x1.min_lvl > t.min_lvl) ? "↑" :

jobs

.Where(x4 => x4.job_id == x1.job_id - 1)

.Select(x4 => new

{

x4.min_lvl

}).Any(t => x1.min_lvl < t.min_lvl) ? "↓" : "-")

})

.OrderBy(t => t.job_id);

TopPage

ファイル名 No38.linq

節名 1-6 相関サブクエリで行と行を比較する

項目名 前年との比較結果を一覧表示する

ページ P107の下のSQL

T-SQL SELECT j1.job_id, j1.min_lvl,

CASE WHEN j1.min_lvl = j2.min_lvl THEN '→'

WHEN j1.min_lvl > j2.min_lvl THEN '↑'

WHEN j1.min_lvl < j2.min_lvl THEN '↓'

ELSE '-' END AS [var]

FROM jobs AS j1, jobs AS j2

WHERE j2.job_id = j1.job_id - 1

ORDER BY j1.job_id

LINQコード jobs

28

.SelectMany(j2 => jobs,

(j1, j2) => new{j1, j2})

.Where(x1 => x1.j2.job_id == x1.j1.job_id - 1)

.Select(x1 => new

{

x1.j1.job_id,

x1.j1.min_lvl,

var = (x1.j1.min_lvl == x1.j2.min_lvl ? "→" :

x1.j1.min_lvl > x1.j2.min_lvl ? "↑" :

x1.j1.min_lvl < x1.j2.min_lvl ? "↓" : "-")

})

.OrderBy(t => t.job_id);

TopPage

ファイル名 No39.linq

節名 1-6 相関サブクエリで行と行を比較する

項目 時系列に歯抜けがある場合:直近と比較

ページ P109の 1つ目のSQL

T-SQL SELECT job_id, min_lvl

FROM jobs AS j1

WHERE min_lvl = ( SELECT min_lvl

FROM jobs AS j2

WHERE j2.job_id = (SELECT MAX(job_id)

FROM jobs AS j3

WHERE j1.job_id > j3.job_id))

ORDER BY job_id

LINQコード jobs

.Where(x1 => jobs

.Where(x2 => x2.job_id == jobs

.Where(x3 => x1.job_id > x3.job_id).Max(x3 => x3.job_id))

29

.Select(x2 => new

{

x2.min_lvl

}).Any(t => x1.min_lvl == t.min_lvl))

.Select(x1 => new

{

x1.job_id,

x1.min_lvl

})

.OrderBy(t => t.job_id);

TopPage

ファイル名 No40.linq

節名 1-6 相関サブクエリで行と行を比較する

項目名 時系列に歯抜けがある場合:直近と比較

ページ P109の 2つ目のSQL

T-SQL SELECT j2.job_id AS pre_job_id,

j1.job_id AS now_job_id

FROM jobs AS j1, jobs AS j2

WHERE j1.min_lvl = j2.min_lvl

AND j2.job_id = (SELECT MAX(job_id)

FROM jobs AS j3

WHERE j1.job_id > j3.job_id)

ORDER BY now_job_id

LINQコード jobs

.SelectMany(j2 => jobs,

(j1, j2) => new{j1, j2})

.Where(x1 => x1.j1.min_lvl == x1.j2.min_lvl && x1.j2.job_id == jobs

.Where(x2 => x1.j1.job_id > x2.job_id).Max(x2 =>

x2.job_id))

30

.Select(x1 => new

{

pre_job_id = x1.j2.job_id,

now_job_id = x1.j1.job_id

})

.OrderBy(t => t.now_job_id);

TopPage

ファイル名 No41.linq

節名 1-6 相関サブクエリで行と行を比較する

項目名 時系列に歯抜けがある場合:直近と比較

ページ P109の 3つ目のSQL

T-SQL SELECT j2.job_id AS pre_job_id,

j1.job_id AS now_job_id,

j2.min_lvl AS pre_min_lvl,

j1.min_lvl AS now_min_lvl,

-- min_lvlはtinyintなので、負数を持てない

CASE WHEN j1.min_lvl >= j2.min_lvl THEN j1.min_lvl - j2.min_lvl

ELSE 0 END AS diff_plus,

CASE WHEN j1.min_lvl < j2.min_lvl THEN j2.min_lvl - j1.min_lvl

ELSE 0 END AS diff_minus

FROM jobs AS j1, jobs AS j2

WHERE j2.job_id = (SELECT MAX(job_id)

FROM jobs AS j3

WHERE j1.job_id > j3.job_id)

ORDER BY now_job_id

LINQコード jobs

.SelectMany(j2 => jobs,

(j1, j2) => new{j1, j2})

.Where(x1 => x1.j2.job_id == jobs

31

.Where(x2 => x1.j1.job_id > x2.job_id).Max(x2 => x2.job_id))

.Select(x1 => new

{

pre_job_id = x1.j2.job_id,

now_job_id = x1.j1.job_id,

pre_min_lvl = x1.j2.min_lvl,

now_min_lvl = x1.j1.min_lvl,

diff_plus = (x1.j1.min_lvl >= x1.j2.min_lvl ? x1.j1.min_lvl - x1.j2.min_lvl : 0),

diff_minus = (x1.j1.min_lvl < x1.j2.min_lvl ? x1.j2.min_lvl - x1.j1.min_lvl : 0)

})

.OrderBy(t => t.now_job_id);

TopPage

ファイル名 No43.linq

節名 1-6 相関サブクエリで行と行を比較する

項目名 移動累計と移動平均

ページ P111の下のSQL

T-SQL SELECT j1.job_id, j1.min_lvl,

(SELECT SUM(min_lvl)

FROM jobs AS j2

WHERE j1.job_id >= j2.job_id) AS sum_min_lvl

FROM jobs AS j1

ORDER BY j1.job_id

LINQコード jobs

.Select(x1 => new

{

x1.job_id,

x1.min_lvl,

sum_min_lvl = jobs

32

.Where(x2 => x1.job_id >= x2.job_id).Sum(x2 => x2.min_lvl)

})

.OrderBy(t => t.job_id);

TopPage

ファイル名 No44.linq

節名 1-6 相関サブクエリで行と行を比較する

項目名 移動累計と移動平均

ページ P113の下のSQL

T-SQL SELECT j1.job_id, j1.min_lvl,

(SELECT SUM(min_lvl)

FROM jobs AS j2

WHERE j1.job_id >= j2.job_id

AND (SELECT COUNT(*)

FROM jobs AS j3

WHERE j3.job_id

BETWEEN j2.job_id AND j1.job_id) <= 3)

AS mvg_min_lvl

FROM jobs AS j1

ORDER BY j1.job_id

LINQコード jobs

.Select(x1 => new

{

x1.job_id,

x1.min_lvl,

mvg_min_lvl = jobs

.Where(x2 => x1.job_id >= x2.job_id && jobs

.Where(x3 => x3.job_id >= x2.job_id && x3.job_id <= x1.job_id).Cou

nt() <= 3).Sum(x2 => (int?)(x2.min_lvl))

})

.OrderBy(t => t.job_id);

33

TopPage

ファイル名 No45.linq

節名 1-6 相関サブクエリで行と行を比較する

項目名 移動累計と移動平均

ページ P114の上のSQL

T-SQL SELECT j1.job_id, j1.min_lvl,

(SELECT SUM(min_lvl)

FROM jobs AS j2

WHERE j1.job_id >= j2.job_id

AND (SELECT COUNT(*)

FROM jobs AS j3

WHERE j3.job_id

BETWEEN j2.job_id AND j1.job_id) <= 3

HAVING COUNT(*) = 3) AS mvg_min_lvl

FROM jobs AS j1

ORDER BY j1.job_id

LINQコード jobs

.Select(x1 => new

{

x1.job_id,

x1.min_lvl,

mvg_min_lvl = jobs

.Where(x2 => x1.job_id >= x2.job_id && jobs

.Where(x3 => x3.job_id >= x2.job_id && x3.job_id <=

x1.job_id).Count() <= 3)

.Where(x2 => jobs

.Where(x4 => x1.job_id >= x4.job_id && jobs

.Where(x5 => x5.job_id >= x4.job_id &&

x5.job_id <= x1.job_id).Count() <= 3).Count() == 3).Sum(x2 => (int?)(x2.min_lvl))

})

34

.OrderBy(t => t.job_id);

TopPage

ファイル名 No46.linq

節名 1-6 相関サブクエリで行と行を比較する

項目名 オーバーラップする期間を調べる

ページ P117

T-SQL SELECT job_id, min_lvl, max_lvl

FROM jobs AS j1

WHERE EXISTS

(SELECT *

FROM jobs AS j2

WHERE j1.job_id <> j2.job_id

AND (j1.min_lvl BETWEEN j2.min_lvl AND j2.max_lvl

OR j1.max_lvl BETWEEN j2.min_lvl AND j2.max_lvl))

LINQコード jobs

.Where(x1 => jobs.Any(x2 => x1.job_id != x2.job_id && (x1.min_lvl >= x2.min_lvl && x1.min_lvl <= x2.max_lvl || x1.max_lvl

>= x2.min_lvl && x1.max_lvl <= x2.max_lvl)))

.Select(x1 => new

{

x1.job_id,

x1.min_lvl,

x1.max_lvl

});

TopPage

ファイル名 No47.linq

節名 1-7 SQLで集合演算

35

項目名 テーブル同士のコンペア

ページ P125

T-SQL SELECT COUNT(*) AS row_cnt

FROM (SELECT *

FROM jobs

UNION

SELECT *

FROM jobs) tmp

LINQコード jobs

.Select(x2 => new

{

x2.job_id,

x2.job_desc,

x2.min_lvl,

x2.max_lvl

})

.Union(jobs

.Select(x3 => new

{

x3.job_id,

x3.job_desc,

x3.min_lvl,

x3.max_lvl

}))

.Select(x1 => new

{

row_cnt = jobs

.Select(x5 => new

{

x5.job_id,

x5.job_desc,

x5.min_lvl,

x5.max_lvl

36

})

.Union(jobs

.Select(x6 => new

{

x6.job_id,

x6.job_desc,

x6.min_lvl,

x6.max_lvl

})).Count()

})

.Distinct();

TopPage

ファイル名 No48.linq

節名 1-7 SQLで集合演算

項目名 等しい部分集合を見つける

ページ P134の上のSQL

T-SQL SELECT t1.au_id AS au1, t2.au_id AS au2

FROM titleauthor AS t1, titleauthor AS t2

WHERE t1.au_id < t2.au_id

AND t1.title_id = t2.title_id

GROUP BY t1.au_id, t2.au_id

HAVING COUNT(*) = (SELECT COUNT(*)

FROM titleauthor AS t3

WHERE t3.au_id = t1.au_id)

AND COUNT(*) = (SELECT COUNT(*)

FROM titleauthor AS t4

WHERE t4.au_id = t2.au_id)

LINQコード titleauthors

.SelectMany(t2 => titleauthors,

37

(t1, t2) => new{t1, t2})

.Where(x1 => string.Compare(x1.t1.au_id,x1.t2.au_id) < 0 && x1.t1.title_id == x1.t2.title_id)

.GroupBy(x1 => new{grKey1 = x1.t1.au_id, grKey2 = x1.t2.au_id})

.Where(g1 => g1.Count() == titleauthors

.Where(x2 => x2.au_id == g1.Key.grKey1).Count() && g1.Count() == titleauthors

.Where(x3 => x3.au_id ==

g1.Key.grKey2).Count())

.Select(g1 => new

{

au1 = g1.Key.grKey1,

au2 = g1.Key.grKey2

});

TopPage

ファイル名 No49.linq

節名 1-8 EXISTS述語の使い方

項目名 テーブルに存在「しない」データを探す

ページ P146の上のSQL

T-SQL SELECT DISTINCT s1.stor_id, s2.state

FROM stores AS s1 CROSS JOIN stores AS s2

WHERE NOT EXISTS

(SELECT *

FROM stores AS s3

WHERE s1.stor_id = s3.stor_id

AND s2.state = s3.state)

LINQコード stores

.SelectMany(s2 => stores,

(s1, s2) => new{s1, s2})

.Where(x1 => !(stores.Any(x2 => x1.s1.stor_id == x2.stor_id && x1.s2.state == x2.state)))

.Select(x1 => new

38

{

x1.s1.stor_id,

x1.s2.state

})

.Distinct();

TopPage

ファイル名 No50.linq

節名 1-8 EXISTS述語の使い方

項目名 テーブルに存在「しない」データを探す

ページ P146の下のSQL

T-SQL SELECT s1.stor_id, s2.state

FROM stores AS s1, stores AS s2

EXCEPT

SELECT stor_id, state

FROM stores

ORDER BY s1.stor_id

LINQコード stores

.SelectMany(s2 => stores,

(s1, s2) => new{s1, s2})

.Select(x1 => new

{

x1.s1.stor_id,

x1.s2.state

})

.Except(stores

.Select(x2 => new

{

x2.stor_id,

x2.state

39

}))

.OrderBy(t => t.stor_id);

TopPage

ファイル名 No51.linq

節名 1-8 EXISTS述語の使い方

項目名 肯定⇔二重否定の変換に慣れよう

ページ P147

T-SQL SELECT DISTINCT stor_id

FROM sales AS s1

WHERE NOT EXISTS

(SELECT *

FROM sales AS s2

WHERE s2.stor_id = s1.stor_id

AND s2.qty < 10)

LINQコード sales

.Where(x1 => !(sales.Any(x2 => x2.stor_id == x1.stor_id && x2.qty < 10)))

.Select(x1 => new

{

x1.stor_id

})

.Distinct();

TopPage

ファイル名 No52.linq

節名 1-8 EXISTS述語の使い方

項目名 肯定⇔二重否定の変換に慣れよう

40

ページ P149の上のSQL

T-SQL SELECT DISTINCT stor_id

FROM sales AS s1

WHERE title_id IN ('ps2091', 'pc8888')

AND NOT EXISTS

(SELECT *

FROM sales AS s2

WHERE s2.stor_id = s1.stor_id

AND 1 = CASE WHEN title_id = 'ps2091' AND qty < 20 THEN 1

WHEN title_id = 'pc8888' AND qty < 50 THEN 1

ELSE 0 END)

LINQコード sales

.Where(x1 => (new string[]{"ps2091", "pc8888"}).Contains(x1.title_id) && !(sales.Any(x2 => x2.stor_id == x1.stor_id && 1

== (x2.title_id == "ps2091" && x2.qty < 20 ? 1 :

x2.title_id == "pc8888" && x2.qty < 50 ? 1 : 0))))

.Select(x1 => new

{

x1.stor_id

})

.Distinct();

TopPage

ファイル名 No53.linq

節名 1-8 EXISTS述語の使い方

項目名 肯定⇔二重否定の変換に慣れよう

ページ P149の下のSQL

T-SQL SELECT stor_id

FROM sales AS s1

WHERE title_id IN ('ps2091', 'pc8888')

AND NOT EXISTS

41

(SELECT *

FROM sales AS s2

WHERE s2.stor_id = s1.stor_id

AND 1 = CASE WHEN title_id = 'ps2091' AND qty < 20 THEN 1

WHEN title_id = 'pc8888' AND qty < 50 THEN 1

ELSE 0 END)

GROUP BY stor_id

HAVING COUNT(*) = 2

LINQコード sales

.Where(x1 => (new string[]{"ps2091", "pc8888"}).Contains(x1.title_id) && !(sales.Any(x2 => x2.stor_id == x1.stor_id && 1

== (x2.title_id == "ps2091" && x2.qty < 20 ? 1 :

x2.title_id == "pc8888" && x2.qty < 50 ? 1 : 0))))

.GroupBy(x1 => new{grKey1 = x1.stor_id})

.Where(g1 => g1.Count() == 2)

.Select(g1 => new

{

stor_id = g1.Key.grKey1

});

TopPage

ファイル名 N054.linq

節名 1-8 EXISTS述語の使い方

項目名 演習問題8-1 配列テーブル-行待ちの場合

ページ P156

T-SQL SELECT DISTINCT au_id

FROM titleauthor AS t1

WHERE NOT EXISTS

(SELECT *

FROM titleauthor AS t2

WHERE t1.au_id = t2.au_id

42

AND (t2.au_ord <> 1 OR t2.au_ord IS NULL))

GROUP BY au_id

HAVING COUNT(*) = 2

LINQコード titleauthors

.Where(x1 => !(titleauthors.Any(x2 => x1.au_id == x2.au_id && (x2.au_ord != 1 || x2.au_ord == null))))

.GroupBy(x1 => new{grKey1 = x1.au_id})

.Where(g1 => g1.Count() == 2)

.Select(g1 => new

{

au_id = g1.Key.grKey1

})

.Distinct();

TopPage

ファイル名 No55.linq

節名 1-8 EXISTS述語の使い方

項目名 演習問題8-1 配列テーブル-行待ちの場合

ページ P156

T-SQL SELECT DISTINCT au_id

FROM titleauthor AS t1

WHERE 1 = ALL

(SELECT au_ord

FROM titleauthor AS t2

WHERE t1.au_id = t2.au_id)

GROUP BY au_id

HAVING COUNT(*) = 2

LINQコード titleauthors

.Where(x1 => titleauthors

.Where(x2 => x1.au_id == x2.au_id)

.Select(x2 => new

43

{

x2.au_ord

}).All(t => 1 == t.au_ord))

.GroupBy(x1 => new{grKey1 = x1.au_id})

.Where(g1 => g1.Count() == 2)

.Select(g1 => new

{

au_id = g1.Key.grKey1

})

.Distinct();

TopPage

ファイル名 N056.linq

節名 1-8 EXISTS述語の使い方

項目名 演習問題8-1 配列テーブル-行待ちの場合

ページ P156

T-SQL SELECT au_id

FROM titleauthor

GROUP BY au_id

HAVING SUM(CASE WHEN au_ord = 1 THEN 1 ELSE 0 END) = 2

LINQコード titleauthors

.GroupBy(x1 => new {grKey1 = x1.au_id})

.Where(g1 => g1.Sum(x1 => (int?)((x1.au_ord == 1 ? 1 : 0))) == 2)

.Select(g1 => new

{

au_id = g1.Key.grKey1

});

TopPage

44

ファイル名 No57.linq

節名 1-8 EXISTS述語の使い方

項目名 演習問題8-1 配列テーブル-行待ちの場合

ページ P156

T-SQL SELECT au_id

FROM titleauthor

GROUP BY au_id

HAVING MAX(au_ord) = 1 AND MIN(au_ord) = 1

AND COUNT(*) = 2

LINQコード titleauthors

.GroupBy(x1 => new{grKey1 = x1.au_id})

.Where(g1 => g1.Max(x1 => x1.au_ord) == 1 && g1.Min(x1 => x1.au_ord) == 1 && g1.Count() == 2)

.Select(g1 => new

{

au_id = g1.Key.grKey1

});

TopPage

ファイル名 No58.linq

節名 1-8 EXISTS述語の使い方

項目名 演習問題8-3 素数を求める

ページ P157

T-SQL SELECT job_id AS prime

FROM jobs AS divided

WHERE job_id > 1

AND NOT EXISTS

(SELECT *

FROM jobs AS divisor

45

WHERE divisor.job_id <= divided.job_id / 2

AND divisor.job_id <> 1

AND divided.job_id % divisor.job_id = 0)

ORDER BY prime

LINQコード jobs

.Where(x1 => x1.job_id > 1 && !(jobs.Any(x2 => x2.job_id <= x1.job_id / 2 && x2.job_id != 1 && x1.job_id % x2.job_id ==

0)))

.Select(x1 => new

{

prime = x1.job_id

})

.OrderBy(t => t.prime);

TopPage

ファイル名 No59.linq

節名 1-9 SQLで数列を扱う

項目名 連番を作ろう

ページ P160

T-SQL SELECT j1.job_id + (j2.job_id * 10) AS seq

FROM jobs AS j1 CROSS JOIN jobs AS j2

WHERE j1.job_id <= 9 AND j2.job_id <= 9

ORDER BY seq

LINQコード jobs

.SelectMany(j2 => jobs,

(j1, j2) => new{j1, j2})

.Where(x1 => x1.j1.job_id <= 9 && x1.j2.job_id <= 9)

.Select(x1 => new

{

seq = x1.j1.job_id + (x1.j2.job_id * 10)

})

46

.OrderBy(t => t.seq);

TopPage

ファイル名 No60.linq

節名 1-9 SQLで数列を扱う

項目名 連番を作ろう

ページ P161

T-SQL SELECT j1.job_id + (j2.job_id * 10) AS seq

FROM jobs AS j1 CROSS JOIN jobs AS j2

WHERE j1.job_id <= 9 AND j2.job_id <= 9

AND j1.job_id + (j2.job_id * 10) BETWEEN 1 AND 50

ORDER BY seq

LINQコード jobs

.SelectMany(j2 => jobs,

(j1, j2) => new{j1, j2})

.Where(x1 => x1.j1.job_id <= 9 && x1.j2.job_id <= 9 && x1.j1.job_id + (x1.j2.job_id * 10) >= 1 &&

x1.j1.job_id + (x1.j2.job_id * 10) <= 50)

.Select(x1 => new

{

seq = x1.j1.job_id + (x1.j2.job_id * 10)

})

.OrderBy(t => t.seq);

TopPage

ファイル名 No62.linq

節名 1-9 SQLで数列を扱う

項目名 欠番を全部求める

47

ページ P163の 2つ目のSQL

T-SQL SELECT j1.job_id + (j2.job_id * 10) AS seq

FROM jobs AS j1 CROSS JOIN jobs AS j2

WHERE j1.job_id <= 9 AND j2.job_id <= 9

AND j1.job_id + (j2.job_id * 10) BETWEEN 1 AND 14

AND j1.job_id + (j2.job_id * 10) NOT IN (

SELECT DISTINCT job_id

FROM employee)

LINQコード jobs

.SelectMany(j2 => jobs,

(j1, j2) => new{j1, j2})

.Where(x1 => x1.j1.job_id <= 9 && x1.j2.job_id <= 9 && x1.j1.job_id + (x1.j2.job_id * 10) >= 1 &&

x1.j1.job_id + (x1.j2.job_id * 10) <= 14 && employees

.Select(x2 => new

{

x2.job_id

})

.Distinct().All(t => x1.j1.job_id +

(x1.j2.job_id * 10) != t.job_id))

.Select(x1 => new

{

seq = x1.j1.job_id + (x1.j2.job_id * 10)

});

TopPage

ファイル名 No63_2.linq

節名 1-9 SQLで数列を扱う

項目名 欠番を全部求める

ページ P163の 3つ目のSQL

T-SQL SELECT job_id

48

FROM jobs

WHERE job_id BETWEEN (SELECT MIN(job_id) FROM employee)

AND (SELECT MAX(job_id) FROM employee)

EXCEPT

SELECT job_id FROM employee

LINQコード jobs

.Where(x1 => x1.job_id >= employees.Min(x2 => x2.job_id) && x1.job_id <= employees.Max(x3 => x3.job_id))

.Select(x1 => new

{

x1.job_id

})

.Except(employees

.Select(x4 => new

{

x4.job_id

}));

TopPage

ファイル名 No64.linq

節名 1-9 SQLで数列を扱う

項目名 3人なんだけど、座れますか?

ページ P165

T-SQL SELECT j1.job_id AS start, '~', j2.job_id AS stop

FROM jobs AS j1, jobs AS j2

WHERE j2.job_id = j1.job_id + 2

AND NOT EXISTS

(SELECT *

FROM jobs AS j3

WHERE j3.job_id BETWEEN j1.job_id AND j2.job_id

AND j3.min_lvl >= 100)

49

LINQコード jobs

.SelectMany(j2 => jobs,

(j1, j2) => new{j1, j2})

.Where(x1 => x1.j2.job_id == x1.j1.job_id + 2 && !(jobs.Any(x2 => x2.job_id >= x1.j1.job_id && x2.job_id <= x1.j2.job_id

&& x2.min_lvl >= 100)))

.Select(x1 => new

{

start = x1.j1.job_id,

root_alias_2 = "~",

stop = x1.j2.job_id

});

TopPage

ファイル名 No65.linq

節名 1-9 SQLで数列を扱う

項目数 最大何人まで座れますか?

ページ P169

T-SQL SELECT j1.job_id AS start, j2.job_id AS stop, j2.job_id - j1.job_id + 1 AS cnt

FROM jobs AS j1, jobs AS j2

WHERE j1.job_id <= j2.job_id

AND NOT EXISTS

(SELECT *

FROM jobs AS j3

WHERE (j3.job_id BETWEEN j1.job_id AND j2.job_id

AND j3.max_lvl >= 250)

OR (j3.job_id = j2.job_id + 1 AND j3.max_lvl < 250)

OR (j3.job_id = j1.job_id - 1 AND j3.max_lvl < 250))

LINQコード jobs

.SelectMany(j2 => jobs,

(j1, j2) => new{j1, j2})

50

.Where(x1 => x1.j1.job_id <= x1.j2.job_id && !(jobs.Any(x2 => (x2.job_id >= x1.j1.job_id && x2.job_id <= x1.j2.job_id &&

x2.max_lvl >= 250) || (x2.job_id == x1.j2.job_id + 1 && x2.max_lvl < 250) ||

(x2.job_id == x1.j1.job_id - 1 && x2.max_lvl < 250))))

.Select(x1 => new

{

start = x1.j1.job_id,

stop = x1.j2.job_id,

cnt = x1.j2.job_id - x1.j1.job_id + 1

});

TopPage

ファイル名 No66.linq

節名 1-9 SQLで数列を扱う

項目名 単調増加と単調減少

ページ P172

T-SQL SELECT j1.job_id AS start, j2.job_id AS stop

FROM jobs AS j1, jobs AS j2

WHERE j1.job_id < j2.job_id

AND NOT EXISTS

(SELECT *

FROM jobs AS j3, jobs AS j4

WHERE j3.job_id BETWEEN j1.job_id AND j2.job_id

AND j4.job_id BETWEEN j1.job_id AND j2.job_id

AND j3.job_id < j4.job_id

AND j3.max_lvl >= j4.max_lvl)

LINQコード jobs

.SelectMany(j2 => jobs,

(j1, j2) => new{j1, j2})

.Where(x1 => x1.j1.job_id < x1.j2.job_id && !(jobs

.SelectMany(j4 => jobs,

51

(j3, j4) => new{j3, j4}).Any(x2 => x2.j3.job_id >=

x1.j1.job_id && x2.j3.job_id <= x1.j2.job_id && x2.j4.job_id >= x1.j1.job_id && x2.j4.job_id <=

x1.j2.job_id && x2.j3.job_id < x2.j4.job_id && x2.j3.max_lvl >= x2.j4.max_lvl)))

.Select(x1 => new

{

start = x1.j1.job_id,

stop = x1.j2.job_id

});

TopPage

ファイル名 No67.linq

節名 1-9 SQLで数列を扱う

項目名 単調増加と単調減少

ページ P173

T-SQL SELECT MIN(start) AS start, stop

FROM

(SELECT j1.job_id AS start, MAX(j2.job_id) AS stop

FROM jobs AS j1, jobs AS j2

WHERE j1.job_id < j2.job_id

AND NOT EXISTS

(SELECT *

FROM jobs AS j3, jobs AS j4

WHERE j3.job_id BETWEEN j1.job_id AND j2.job_id

AND j4.job_id BETWEEN j1.job_id AND j2.job_id

AND j3.job_id < j4.job_id

AND j3.max_lvl >= j4.max_lvl)

GROUP BY j1.job_id) TMP

GROUP BY stop

LINQコード jobs

.SelectMany(j2 => jobs,

52

(j1, j2) => new{j1, j2})

.Where(x2 => x2.j1.job_id < x2.j2.job_id && !(jobs

.SelectMany(j4 => jobs,

(j3, j4) => new{j3, j4}).Any(x3 => x3.j3.job_id >=

x2.j1.job_id && x3.j3.job_id <= x2.j2.job_id && x3.j4.job_id >= x2.j1.job_id && x3.j4.job_id <=

x2.j2.job_id && x3.j3.job_id < x3.j4.job_id && x3.j3.max_lvl >= x3.j4.max_lvl)))

.GroupBy(x2 => new{grKey1 = x2.j1.job_id})

.Select(g1 => new

{

start = g1.Key.grKey1,

stop = g1.Max(x2 => x2.j2.job_id)

})

.GroupBy(x1 => new{grKey2 = x1.stop})

.Select(g2 => new

{

start = g2.Min(x1 => x1.start),

stop = g2.Key.grKey2

});

TopPage

ファイル名 No68.linq

節名 1-9 SQLで数列を扱う

項目名 演習問題9-2 シーケンスを求める

ページ P175

T-SQL SELECT j1.job_id AS start, '~', j2.job_id AS stop

FROM jobs AS j1, jobs AS j2, jobs AS j3

WHERE j2.job_id = j1.job_id + 2

AND j3.job_id BETWEEN j1.job_id AND j2.job_id

GROUP BY j1.job_id, j2.job_id

HAVING COUNT(*) = SUM(CASE WHEN j3.min_lvl < 100 THEN 1 ELSE 0 END)

53

LINQコード jobs

.SelectMany(j2 => jobs,

(j1, j2) => new{j1, j2})

.SelectMany(j3 => jobs,

(x1, j3) => new{x1, j3})

.Where(x2 => x2.x1.j2.job_id == x2.x1.j1.job_id + 2 && x2.j3.job_id >= x2.x1.j1.job_id && x2.j3.job_id

<= x2.x1.j2.job_id)

.GroupBy(x2 => new{grKey1 = x2.x1.j1.job_id, grKey2 = x2.x1.j2.job_id})

.Where(g1 => g1.Count() == g1.Sum(x2 => (x2.j3.min_lvl < 100 ? 1 : 0)))

.Select(g1 => new

{

start = g1.Key.grKey1,

root_alias_2 = "~",

stop = g1.Key.grKey2

});

TopPage

ファイル名 No69.linq

節名 1-9 SQLで数列を扱う

項目名 演習問題9-3 シーケンスを全て求める

ページ P175

T-SQL SELECT j1.job_id AS start, j2.job_id AS stop, j2.job_id - j1.job_id + 1 AS cnt

FROM jobs AS j1, jobs AS j2, jobs AS j3

WHERE j1.job_id <= j2.job_id

AND j3.job_id BETWEEN j1.job_id - 1 AND j2.job_id + 1

GROUP BY j1.job_id, j2.job_id

HAVING COUNT(*) = SUM(CASE WHEN j3.job_id BETWEEN j1.job_id AND j2.job_id

AND j3.max_lvl < 250 THEN 1

WHEN j3.job_id = j2.job_id + 1

AND j3.max_lvl >= 250 THEN 1

WHEN j3.job_id = j1.job_id - 1

54

AND j3.max_lvl >= 250 THEN 1

ELSE 0 END)

LINQコード jobs

.SelectMany(j2 => jobs,

(j1, j2) => new{j1, j2})

.SelectMany(j3 => jobs,

(x1, j3) => new{x1, j3})

.Where(x2 => x2.x1.j1.job_id <= x2.x1.j2.job_id && x2.j3.job_id >= x2.x1.j1.job_id - 1 && x2.j3.job_id

<= x2.x1.j2.job_id + 1)

.GroupBy(x2 => new{grKey1 = x2.x1.j1.job_id, grKey2 = x2.x1.j2.job_id})

.Where(g1 => g1.Count() == g1.Sum(x2 => (x2.j3.job_id >= g1.Key.grKey1 && x2.j3.job_id <= g1.Key.grKey2 && x2.j3.max_lvl

< 250 ? 1 :

x2.j3.job_id == g1.Key.grKey2 + 1 &&

x2.j3.max_lvl >= 250 ? 1 :

x2.j3.job_id == g1.Key.grKey1 - 1 &&

x2.j3.max_lvl >= 250 ? 1 : 0)))

.Select(g1 => new

{

start = g1.Key.grKey1,

stop = g1.Key.grKey2,

cnt = g1.Key.grKey2 - g1.Key.grKey1 + 1

});

TopPage

ファイル名 No70.linq

節名 1-10 帰ってきたHAVING句

項目名 各隊、総員点呼!

ページ P177

T-SQL SELECT state, au_id

FROM authors AS a1

55

WHERE NOT EXISTS

(SELECT *

FROM authors AS a2

WHERE a1.state = a2.state

AND [contract] = 0)

LINQコード authors

.Where(x1 => !(authors.Any(x2 => x1.state == x2.state && x2.contract == (0 == 0 ? false : true))))

.Select(x1 => new

{

x1.state,

x1.au_id

});

TopPage

ファイル名 No71.linq

節名 1-10 帰ってきたHAVING句

項目名 各隊、総員点呼!

ページ P178

T-SQL SELECT state

FROM authors

GROUP BY state

HAVING COUNT(*) = SUM(CASE WHEN contract = 1 THEN 1 ELSE 0 END)

LINQコード authors

.GroupBy(x1 => new {grKey1 = x1.state})

.Where(g1 => g1.Count() == g1.Sum(x1 => (int?)((x1.contract == (1 == 0 ? false : true) ? 1 : 0))))

.Select(g1 => new

{

state = g1.Key.grKey1

});

56

TopPage

ファイル名 No72.linq

節名 1-10 帰ってきたHAVING句

項目名 一意集合と多集合

ページ P182の上のSQL

T-SQL SELECT au_id

FROM titleauthor

GROUP BY au_id

HAVING COUNT(au_ord) <> COUNT(DISTINCT au_ord)

LINQコード titleauthors

.GroupBy(x1 => new {grKey1 = x1.au_id})

.Where(g1 => g1.Count(x1 => x1.au_ord != null) != g1.Where(x1 => x1.au_ord != null).Select(x1 =>

(int?)(x1.au_ord)).Distinct().Count())

.Select(g1 => new

{

au_id = g1.Key.grKey1

});

TopPage

ファイル名 No73.linq

節名 1-10 帰ってきたHAVING句

項目名 一意集合と多集合

ページ P182の下のSQL

T-SQL SELECT au_id, CASE WHEN COUNT(au_ord) <> COUNT(DISTINCT au_ord)

THEN 'ダブリあり'

ELSE 'ダブリなし' END AS status

FROM titleauthor

GROUP BY au_id

57

LINQコード titleauthors

.GroupBy(x1 => new {grKey1 = x1.au_id})

.Select(g1 => new

{

au_id = g1.Key.grKey1,

status = (g1.Count(x1 => x1.au_ord != null) != g1.Where(x1 => x1.au_ord != null).Select(x1 => (int?)(x1.au_ord)).Distinct().

Count() ? "ダブリあり" : "ダブリなし")

});

TopPage

ファイル名 No74.linq

節名 1-10 帰ってきたHAVING句

項目名 一意集合と多集合

ページ P183

T-SQL SELECT au_id, au_ord

FROM titleauthor AS t1

WHERE EXISTS

(SELECT *

FROM titleauthor AS t2

WHERE t1.au_id = t2.au_id

AND t1.title_id <> t2.title_id

AND t1.au_ord = t2.au_ord)

LINQコード titleauthors

.Where(x1 => titleauthors.Any(x2 => x1.au_id == x2.au_id && x1.title_id != x2.title_id && x1.au_ord == x2.au_ord))

.Select(x1 => new

{

x1.au_id,

x1.au_ord

});

TopPage

58

ファイル名 No75.linq

節名 1-10 帰ってきたHAVING句

項目名 欠番を探せ:発展版

ページ P185の 1つ目のSQL

T-SQL SELECT '歯抜けあり' AS gap

FROM jobs

HAVING COUNT(*) <> MAX(job_id) - MIN(job_id) + 1

LINQコード jobs

.Where(x1 => jobs.Count() != jobs.Max(x3 => x3.job_id) - jobs.Min(x4 => x4.job_id) + 1)

.Select(x1 => new

{

gap = "歯抜けあり"

})

.Distinct();

TopPage

ファイル名 No76.linq

節名 1-10 帰ってきたHAVING句

項目名 欠番を探せ:発展版

ページ P185の2つ目のSQL

T-SQL SELECT CASE WHEN COUNT(*) = 0 THEN 'テーブルが空です'

WHEN COUNT(*) <> MAX(job_id) - MIN(job_id) + 1 THEN '歯抜けあり'

ELSE '連続' END AS gap

FROM jobs

LINQコード jobs

.Select(x1 => new

{

59

gap = (jobs.Count() == 0 ? "テーブルが空です" :

jobs.Count() != jobs.Max(x4 => x4.job_id) - jobs.Min(x5 => x5.job_id) + 1 ? "歯抜けあり" : "連続")

})

.Distinct();

TopPage

ファイル名 No77.linq

節名 1-10 帰ってきたHAVING句

項目名 欠番を探せ:発展版

ページ P185の3つ目のSQL

T-SQL SELECT CASE WHEN COUNT(*) = 0 OR MIN(job_id) > 1 THEN 1

ELSE (SELECT MIN(job_id + 1)

FROM jobs AS j1

WHERE NOT EXISTS

(SELECT *

FROM jobs AS j2

WHERE j2.job_id = j1.job_id +1)) END AS gap

FROM jobs

LINQコード jobs

.Select(x1 => new

{

gap = (jobs.Count() == 0 || jobs.Min(x3 => x3.job_id) > 1 ? 1 : jobs

.Where(x4 => !(jobs.Any(x5 => x5.job_id ==

x4.job_id + 1))).Min(x4 => x4.job_id + 1))

})

.Distinct();

TopPage

ファイル名 No78.linq

60

節名 1-10 帰ってきたHAVING句

項目名 集合にきめ細やかな条件を設定する

ページ P187の上のSQL

T-SQL SELECT au_id

FROM titleauthor

GROUP BY au_id

HAVING COUNT(*) * 0.5 <= SUM(CASE WHEN royaltyper >= 80 THEN 1 ELSE 0 END)

LINQコード titleauthors

.GroupBy(x1 => new {grKey1 = x1.au_id})

.Where(g1 => g1.Count() * 0.5m <= g1.Sum(x1 => (int?)((x1.royaltyper >= 80 ? 1 : 0))))

.Select(g1 => new

{

au_id = g1.Key.grKey1

});

TopPage

ファイル名 No79.linq

節名 1-10 帰ってきたHAVING句

項目名 集合にきめ細やかな条件を設定する

ページ P187の下のSQL

T-SQL SELECT au_id

FROM titleauthor

GROUP BY au_id

HAVING SUM(CASE WHEN royaltyper >= 50 AND au_ord = 1 THEN 1 ELSE 0 END) >

SUM(CASE WHEN royaltyper >= 50 AND au_ord <> 1 THEN 1 ELSE 0 END)

LINQコード titleauthors

.GroupBy(x1 => new {grKey1 = x1.au_id})

.Where(g1 => g1.Sum(x1 => (int?)((x1.royaltyper >= 50 && x1.au_ord == 1 ? 1 : 0))) > g1.Sum(x1 =>

(int?)((x1.royaltyper >= 50 && x1.au_ord != 1 ? 1 : 0))))

61

.Select(g1 => new

{

au_id = g1.Key.grKey1

});

TopPage

ファイル名 No80.linq

節名 1-10 帰ってきたHAVING句

項目名 集合にきめ細やかな条件を設定する

ページ P188

T-SQL SELECT au_id

FROM titleauthor

GROUP BY au_id

HAVING AVG(CASE WHEN au_ord = 1 THEN royaltyper ELSE NULL END) >

AVG(CASE WHEN au_ord <> 1 THEN royaltyper ELSE NULL END)

LINQコード titleauthors

.GroupBy(x1 => new{grKey1 = x1.au_id})

.Where(g1 => g1.Average(x1 => (x1.au_ord == 1 ? x1.royaltyper : null)) > g1.Average(x1 => (x1.au_ord != 1 ? x1.royaltyper

: null)))

.Select(g1 => new

{

au_id = g1.Key.grKey1

});

TopPage

ファイル名 No80_2.linq

節名 1-10 帰ってきたHAVING句

項目名 集合にきめ細やかな条件を設定する

62

ページ P189

T-SQL SELECT au_id

FROM titleauthor

GROUP BY au_id

HAVING AVG(CASE WHEN au_ord = 1 THEN royaltyper ELSE 0 END) >

AVG(CASE WHEN au_ord <> 1 THEN royaltyper ELSE 0 END)

LINQコード titleauthors

.GroupBy(x1 => new{grKey1 = x1.au_id})

.Where(g1 => g1.Average(x1 => (x1.au_ord == 1 ? x1.royaltyper : (int?)(0))) > g1.Average(x1 => (x1.au_ord != 1 ?

x1.royaltyper : (int?)(0))))

.Select(g1 => new

{

au_id = g1.Key.grKey1

});

TopPage

63