sqlcompiler for linq(c#)のサンプル - sanki- · pdf fileno23.linq 1-4 having句の力...
Post on 14-Mar-2018
217 Views
Preview:
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
top related