iPhone X の顔認証「Face ID」を 150ドルで突破された!

iPhone X の顔認証「Face ID」を 150ドルで突破された

「Computer Weekly 日本語版 2018 年 1 月 10 日号」を見ていたら、「iPhone X の顔認証「Face ID」を 150ドルで突破された」と出ていました。
『顔認証テクノロジー「Face ID」は 150 ドルで突破できる。一般ユーザーが利用したり対象になったりする可能性は低いが、突破できることは証明された。』と出ていました。

ググってみると同様の記事があちらこちらに。。。
『iPhone Xの顔認証がマスクで突破される』とか。

「Face ID」をどうやって騙した?

要約すると、「ネットワークセキュリティの専門家が 3D プリンタで作成したマスクを使って、Apple の最新主力スマートフォン「iPhone X」の顔認証テクノロジー「Face ID」を擦り抜けた」と言うものでした。
ネットワークセキュリティの専門家と言うのは、ベトナムのセキュリティ企業 Bkav のことで、マスクを 5 日間で作成したそうです。
3D プリンタで作成した輪郭、2D 画像、アーティストが形成した鼻を使い、顔の肌周りに特殊処理を施したもので、製作総額は 150 ドル(約 1 万 7000 円)だったそうです。

まぁ、安価な価格で破られてしまったことは問題ですが、実情その手法を使ってデータを盗み出すかと言えばそれは一般の人には当てはまらない行為かと思います。
安価な価格と言えどもかなりのスキルが必要なことは明らかですしね。

また、iPhoneから銀行などにアクセスして、そのまま送金できるかと言えば、他の何らかのセキュリティが掛かっているわけだし、金銭取得は難しそう。
他の用途は、ストーカーとか弱みを握りたいなどの素行調査の一環としてなどですね。いろいろな目的でデータを盗みたい人が居ると厄介かも。。。

じゃ、顔認証「Face ID」はだめで指紋認証機能「Touch ID」なら大丈夫かと言うと、これも既に破られていますので、同じですね。
顔認証「Face ID」が破られたからと言って、慌てることもないかと思います。

破られたとは言え、生体認証は素晴らしい機能で普段使いには十分な性能を発揮してくれると思います。
安価なセキュリティは、破られる運命なので絶対を期待するのを止めれば良いだけのことです^^

以上、ふと思ったことでした。

スマホのGoogleカレンダーで共有相手の予定・カレンダーが見えない

スマホのGoogleカレンダーで共有相手の予定・カレンダーが見えない

本日の仕事でGoogleカレンダーの共有をしようとなり、PCからGoogleカレンダーの共有設定をしました。
PCで確かめたところちゃんと共有できているにも関わらず、スマホでは共有相手の予定・カレンダーが見えない状態になっていました。

更新を試して表示されず、困ったなぁと思ってググってみても解決策が簡単に見つからず、更に困ったなぁ。。。状態。

PCでは共有できているので、スマホの設定だけなんだろう思い、とにかく触るまくっていると、あっ!!こんなところに!

スマホのGoogleカレンダーで共有相手の予定が見えない原因

スマホのGoogleカレンダーで共有相手の予定が見えない原因

上の写真の赤枠のところ。。。「もっと見る」
こんなの今まで無かったような、と思い開けてみると、現れました、共有相手のメールアドレス^^

しかし、設定はさらに続きます。
共有相手のメールアドレスをタップします。
すると
・同期
・名前
・通知関連
の設定画面になります。

同期がOFFになっていると、予定はカレンダーに表示されません。
ここがどうやら今回の原因のようです。

同期をONにして戻ると、ちゃんとカレンダー共有相手の予定がカレンダーに反映されてました^^
めでたしめでたし^^

私がGoogleで検索しても簡単に見つからなかったので、備忘録も兼ねて紹介しておきます。
以上、スマホのGoogleカレンダーで共有相手の予定・カレンダーが見えないでした。

IX Web Hosting からメールが届きました(その2)

IX Web Hostingを検討している方へ報告です。
IX Web Hosting からメールが届きました。

ここから↓↓↓↓↓
Hello,

We are excited to announce that
your IX Web Hosting account will soon become part of our sister brand Verio! .

Verio is dedicated to helping customers around the globe create and launch their business and personal websites.
As part of the Endurance International Group, which acquired IX Web Hosting,
we’re excited to be able to offer IX Web Hosting customers faster,
more modern servers, increased network security, and a wide variety of products and services to help customers build and grow their online presence.

After the migration is complete, IX Web Hosting will be discontinued.
But, there’s no need to worry, you don’t have to make any changes right now.

We will send you another email letting you know when the transition is expected to begin, including instructions on anything you need to do.
Once complete, your IX Web Hosting login page will show you how to log in to your new Verio control panel and the Verio Terms of Service will apply to your account and use of Verio’s services.

The Verio Terms of Service can be viewed here: https://www.verio.com/legal/. All of your products, settings, and content – plus a lot more! – should be there ready for you.

For more information about Verio, what you can do to prepare for the transition and what to expect after it’s complete, check out the transition site at http://transition-to-verio.com/.

We’ll keep that site up to date with the latest news and information as the transition occurs.
As always, if you have any questions please contact IX Web Hosting support at 614 534 1961.

Thank you,
The Verio and IX Web Hosting Teams
ここまで↑↑↑↑↑

こんにちは、

我々はそれを発表することに興奮している
あなたのIXウェブホスティングアカウントはすぐに姉妹ブランドVerioの一部になります! 。
Verioは世界中の顧客がビジネスや個人のウェブサイトを作成して立ち上げることを支援することに専念しています。
エンデュランス・インターナショナル・グループの一環として、
IX Webホスティングを取得した、

私たちはIX Web Hostingのお客様により早く提供できることを嬉しく思います。
より現代的なサーバー、ネットワークセキュリティの強化、および幅広い種類の製品とサービスを提供して、お客様のオンラインプレゼンスを構築し成長させるのに役立ちます。

移行が完了すると、IX Webホスティングは中止されます。
しかし、心配する必要はありません、あなたは今すぐ何も変更する必要はありません。

移行がいつ開始されるのかを知らせる別の電子メールをお送りします。
あなたがする必要のあることについての指示も含めて。
完了すると、IX Web Hostingログインページに新しいVerioコントロールパネルへのログイン方法が表示され、Verioの利用規約がアカウントおよびVerioのサービスの使用に適用されます。

Verioの利用規約は、https://www.verio.com/legal/でご覧いただけます。すべての製品、設定、コンテンツに加えてさらに多くのものがあります。 – あなたのために準備ができているはずです。

Verioの詳細については、移行を準備するために何ができるのか、完了後に何を期待するのか、http://transition-to-verio.com/の移行サイトをチェックしてください。

移行が行われると、そのサイトは最新のニュースと情報で最新の状態に保たれます。
いつものように、ご不明な点がございましたら、IX Web Hosting support(614 534 1961)までお問い合わせください。

ありがとうございました、
VerioとIXのWebホスティングチーム

と言う内容でした。買収されちゃったみたい。。。(^^);
中身は変わらないと思うけど。
とりあえず安ければOKで、後は自力でなんとかできる人でないと、怖くて勧められない Web Hosting 会社だから気を付けて契約しましょうね。

以上、IX Web Hosting からメールが届きました(その2)でした。

SQL Server CHECKSUM_AGG チェックサム

CHECKSUM_AGG チェックサム

グループ内にある値のチェックサムが欲しい場合、CHECKSUM_AGG関数を使います。
どのようなケースでチェック
NULL 値は無視されます。

構文:CHECKSUM_AGG ( [ ALL | DISTINCT ] expression )
引数:ALL すべての値にこの集計関数を適用します。 ALL は既定値です。
   DISTINCT CHECKSUM_AGG で、一意な値のチェックサムを返します。
   expression 整数式です。 集計関数とサブクエリは使用できません。

CHECKSUM_AGG は、テーブル内の変更を検出する場合に使用できます。
テーブル内での行の順序は、CHECKSUM_AGG の結果に影響しません。

対象データを変更した場合は、そのリストのチェックサムも変わりますが、 計算の結果チェックサムが変わらない場合もあります。

CHECKSUM_AGG の AGG は、aggregate (集計)の意味です。

下のSQL例文を載せておきます。

declare @tbl1 table(c_point int)
insert into @tbl1 (c_point) values (30)
insert into @tbl1 (c_point) values (40)
insert into @tbl1 (c_point) values (4)
insert into @tbl1 (c_point) values (60)
insert into @tbl1 (c_point) values (60)
insert into @tbl1 (c_point) values (NULL)
insert into @tbl1 (c_point) values (80)

--ALL
--NULLはカウントされません
select CHECKSUM_AGG(c_point) from @tbl1

--DISTINCT
--60が重複しているので結果が異なります
select CHECKSUM_AGG(DISTINCT c_point) from @tbl1

--値が変更されると戻り値も変わります
update @tbl1 set c_point=70 where c_point=80
select CHECKSUM_AGG(c_point) from @tbl1

計算の結果チェックサムが変わらない例
下の例は非常に単純なので実際はこんなに簡単にチェックサムが変わらないことは無いと思いますが。
30 → 31 , 40 → 41 で同じ値を取ります。

declare @tbl1 table(c_point int)
insert into @tbl1 (c_point) values (30)
insert into @tbl1 (c_point) values (40)

--ALL
select CHECKSUM_AGG(c_point) from @tbl1

--値が変更されると戻り値も変わります
update @tbl1 set c_point=31 where c_point=30
update @tbl1 set c_point=41 where c_point=40
select CHECKSUM_AGG(c_point) from @tbl1

以上、SQL Server でチェックサムが欲しい場合、CHECKSUM_AGG関数を使い求めるでした。

SQL Server COUNT カウント 数える

COUNT カウント

SQL Server の対象データの行数を(アイテム数)求めるときに、COUNT関数もしくはCOUNT_BIG関数を使います。
COUNT は常に int データ型の値を返します。
COUNT_BIG は常に bigint データ型の値を返します。

構文:COUNT ( [ ALL | DISTINCT ] expression | * )
    OVER ( [ partition_by_clause ] order_by_clause )
引数:ALL すべての値に集計関数が適用されます。 ALL が既定値です。
   DISTINCT COUNT で、NULL でない一意な値の数を返します。
   expression text 、image、ntext 以外のあらゆる型の式です。
* すべての行を数えて、テーブル内の行の総数を返すことを指定します。
COUNT(*) はパラメーターはとらず、DISTINCT と一緒には使用できません。
COUNT(*) は重複値を除去しないで、指定されたテーブル内の行数を返します。
各行は 1 行としてカウントされ、 これには NULL 値を保持している行も含まれます。
OVER ( [ partition_by_clause ] order_by_clause)
partition_by_clause は、FROM 句で生成された結果セットをパーティションに分割します。

下のSQL例文を載せておきます。

declare @tbl1 table(a_goods varchar(3), b_empNo char(1), c_point int)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','1',80)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','2',60)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','3',40)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','4',30)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','5',50)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('002','6',60)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('002','7',NULL)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('002','8',220)

--ALL
--NULLはカウントされません
select COUNT(ALL c_point) from @tbl1
select COUNT(c_point) from @tbl1 --ALLが無くても同じ結果

--COUNT_BIG
select COUNT_BIG(ALL c_point) from @tbl1

--DISTINCT
--60が重複しているので1つ減ります
select COUNT(DISTINCT c_point) from @tbl1

--*
--行がカウントされます
select COUNT(*) from @tbl1

--over
--a_goods毎にc_pointがカウントされます
select distinct a_goods, COUNT(c_point) OVER (PARTITION BY a_goods) from @tbl1

もう一例
AVG や SUM を共に使用して結果を求める

declare @tbl1 table(a_goods varchar(5), b_empNo char(1), c_point int)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','1',60)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','2',70)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','3',40)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','2',20)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','3',40)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','1',50)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','2',20)

insert into @tbl1 (a_goods,b_empNo,c_point) values ('002','1',70)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('002','2',60)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('002','3',50)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('002','1',80)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('002','2',30)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('002','1',60)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('002','2',40)

insert into @tbl1 (a_goods,b_empNo,c_point) values ('003','1',90)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('003','2',70)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('003','3',40)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('003','3',70)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('003','3',60)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('003','2',50)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('003','1',50)

insert into @tbl1 (a_goods,b_empNo,c_point) values ('004','1',30)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('004','2',50)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('004','3',90)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('004','2',40)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('004','2',10)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('004','3',80)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('004','3',30)

insert into @tbl1 (a_goods,b_empNo,c_point) values ('005','1',80)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('005','2',60)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('005','3',40)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('005','2',30)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('005','3',50)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('005','1',60)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('005','1',20)

--商品、社員ごとのデータ
select distinct a_goods, b_empNo
, COUNT(c_point) over (partition by a_goods,b_empNo) 個数
, SUM(c_point) over (partition by a_goods,b_empNo) 合計
, AVG(c_point) over (partition by a_goods,b_empNo) 平均 
from @tbl1

--社員ごとのデータ
select distinct b_empNo
, COUNT(c_point) over (partition by b_empNo) 個数
, SUM(c_point) over (partition by b_empNo) 合計
, AVG(c_point) over (partition by b_empNo) 平均 
from @tbl1


--商品、社員ごとのデータ
select a_goods, b_empNo
, COUNT(c_point) 個数
, SUM(c_point) 合計
, AVG(c_point) 平均
from @tbl1 group by a_goods, b_empNo order by a_goods, b_empNo

--社員ごとのデータ
select b_empNo
, COUNT(c_point) 個数
, SUM(c_point) 合計
, AVG(c_point) 平均
from @tbl1 group by b_empNo order by b_empNo

以上、SQL Server で COUNT関数を使いアイテム数や行数を求めるでした。

SQL Server MAX 最大

MAX 最大

SQL Server の対象データの最大値を求めるときに、MAX関数を使います。
数値型、日付型、文字列の最大値を求める事ができます。

構文:MAX ( [ ALL | DISTINCT ] expression )
引数:ALL すべての値に集計関数が適用されます。 ALL が既定値です。
   DISTINCT MAX では意味がなく、ISO との互換性を保つためだけに指定可能になっています。
   expression 定数、列、関数、および算術演算子、ビット演算子、文字列演算子の組み合わせを指定します。

下のSQL例文を載せておきます。

declare @tbl1 table(a_goods varchar(3), b_empNo char(1), c_point int)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','1',800000)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','2',600000)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','3',400000)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','4',300000)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','5',500000)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','6',600000)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','7',2200000)

--ALL
select MAX(ALL c_point) from @tbl1
select MAX(c_point) from @tbl1 --ALLが無くても同じ結果

--DISTINCT
--もともと一番大きい値を返すので意味がない
select MAX(DISTINCT c_point) from @tbl1

もう一例
over や group by 句で括って結果を求める

declare @tbl1 table(a_goods varchar(5), b_empNo char(1), c_point int)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','1',60)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','2',70)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','3',40)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','4',20)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','5',40)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','6',50)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','7',20)

insert into @tbl1 (a_goods,b_empNo,c_point) values ('002','1',70)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('002','2',60)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('002','3',50)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('002','4',80)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('002','5',30)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('002','6',60)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('002','7',40)

insert into @tbl1 (a_goods,b_empNo,c_point) values ('003','1',90)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('003','2',70)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('003','3',40)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('003','4',70)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('003','5',60)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('003','6',50)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('003','7',50)

insert into @tbl1 (a_goods,b_empNo,c_point) values ('004','1',30)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('004','2',50)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('004','3',90)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('004','4',40)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('004','5',10)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('004','6',80)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('004','7',30)

insert into @tbl1 (a_goods,b_empNo,c_point) values ('005','1',80)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('005','2',60)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('005','3',40)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('005','4',30)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('005','5',50)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('005','6',60)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('005','7',20)

select MAX(c_point) from @tbl1
select MAX(c_point) from @tbl1 where a_goods='001'
select MAX(c_point) from @tbl1 where a_goods='002'
select MAX(c_point) from @tbl1 where a_goods='003'
select MAX(c_point) from @tbl1 where a_goods='004'
select MAX(c_point) from @tbl1 where a_goods='005'
select a_goods, MAX(c_point) from @tbl1 group by a_goods  --商品の最大値

select distinct b_empNo, MAX(c_point) over (partition by b_empNo) from @tbl1  --社員の最大値 
select b_empNo, MAX(c_point) from @tbl1 group by b_empNo  --社員の最大値

以上、SQL Server で MAX関数を使い最大値を求めるでした。

SQL Server MIN 最小

MIN 最小値

SQL Server の対象データの最小値を求めるときに、MIN関数を使います。
数値型、日付型、文字列の最小値を求める事ができます。

構文:MIN ( [ ALL | DISTINCT ] expression )
引数:ALL すべての値に集計関数が適用されます。 ALL が既定値です。
   DISTINCT MIN では意味がなく、ISO との互換性を保つためだけに指定可能になっています。
   expression 定数、列、関数、および算術演算子、ビット演算子、文字列演算子の組み合わせを指定します。

下のSQL例文を載せておきます。

declare @tbl1 table(a_goods varchar(3), b_empNo char(1), c_point int)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','1',800000)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','2',600000)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','3',400000)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','4',300000)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','5',500000)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','6',600000)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','7',2200000)

--ALL
select MIN(ALL c_point) from @tbl1
select MIN(c_point) from @tbl1 --ALLが無くても同じ結果

--DISTINCT
--もともと一番小さい値を返すので意味がない
select MIN(DISTINCT c_point) from @tbl1

もう一例
over や group by 句で括って結果を求める

declare @tbl1 table(a_goods varchar(5), b_empNo char(1), c_point int)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','1',60)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','2',70)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','3',40)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','4',20)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','5',40)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','6',50)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','7',20)

insert into @tbl1 (a_goods,b_empNo,c_point) values ('002','1',70)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('002','2',60)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('002','3',50)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('002','4',80)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('002','5',30)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('002','6',60)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('002','7',40)

insert into @tbl1 (a_goods,b_empNo,c_point) values ('003','1',90)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('003','2',70)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('003','3',40)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('003','4',70)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('003','5',60)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('003','6',50)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('003','7',50)

insert into @tbl1 (a_goods,b_empNo,c_point) values ('004','1',30)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('004','2',50)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('004','3',90)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('004','4',40)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('004','5',10)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('004','6',80)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('004','7',30)

insert into @tbl1 (a_goods,b_empNo,c_point) values ('005','1',80)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('005','2',60)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('005','3',40)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('005','4',30)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('005','5',50)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('005','6',60)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('005','7',20)

select MIN(c_point) from @tbl1
select MIN(c_point) from @tbl1 where a_goods='001'
select MIN(c_point) from @tbl1 where a_goods='002'
select MIN(c_point) from @tbl1 where a_goods='003'
select MIN(c_point) from @tbl1 where a_goods='004'
select MIN(c_point) from @tbl1 where a_goods='005'
select a_goods, MIN(c_point) from @tbl1 group by a_goods  --商品の最小値

select distinct b_empNo, MIN(c_point) over (partition by b_empNo) from @tbl1  --社員の最小値 
select b_empNo, MIN(c_point) from @tbl1 group by b_empNo  --社員の最小値

以上、SQL Server で MIN関数を使い最小値を求めるでした。

SQL Server SUM 合計

SUM 合計

SQL Server の対象データの合計値の求めるときに、SUM関数を使います。

合計値はいろいろなデータ分析で使用されるので良く使う指標だと思います。

構文:SUM ( [ ALL | DISTINCT ] expression )
引数:ALL すべての値に集計関数が適用されます。 ALL が既定値です。
   DISTINCT 値の出現回数にかかわらず、一意な値の合計を返すことを指定します。
   expression 定数、列、関数、および算術演算子、ビット演算子、文字列演算子の組み合わせを指定します。
NULL 値はすべて無視されます。(対象データになりません)

下のSQL例文を載せておきます。

declare @tbl1 table(a_goods varchar(3), b_empNo char(1), c_point int)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','1',800000)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','2',600000)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','3',400000)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','4',300000)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','5',500000)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','6',600000)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','7',2200000)

--ALL
select SUM(ALL c_point) from @tbl1
select SUM(c_point) from @tbl1 --ALLが無くても同じ結果

--DISTINCT
--600000が2行あるため、重複を省き計算される
select SUM(DISTINCT c_point) from @tbl1

--expression
--型変換、桁あふれに対応する
delete from @tbl1
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','1',800000000)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','2',600000000)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','3',400000000)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','4',300000000)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','5',500000000)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','6',600000000)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','7',1100000000)
select SUM(cast(c_point as bigint)) from @tbl1  --bigint型に
select SUM(cast(c_point as decimal(20,2))) from @tbl1  --decimal型に

もう一例
over や group by 句で括って結果を求める

declare @tbl1 table(a_goods varchar(5), b_empNo char(1), c_point int)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','1',60)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','2',70)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','3',40)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','4',20)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','5',40)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','6',50)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('001','7',20)

insert into @tbl1 (a_goods,b_empNo,c_point) values ('002','1',70)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('002','2',60)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('002','3',50)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('002','4',80)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('002','5',30)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('002','6',60)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('002','7',40)

insert into @tbl1 (a_goods,b_empNo,c_point) values ('003','1',90)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('003','2',70)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('003','3',40)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('003','4',70)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('003','5',60)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('003','6',50)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('003','7',50)

insert into @tbl1 (a_goods,b_empNo,c_point) values ('004','1',30)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('004','2',50)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('004','3',90)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('004','4',40)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('004','5',70)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('004','6',80)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('004','7',30)

insert into @tbl1 (a_goods,b_empNo,c_point) values ('005','1',80)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('005','2',60)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('005','3',40)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('005','4',30)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('005','5',50)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('005','6',60)
insert into @tbl1 (a_goods,b_empNo,c_point) values ('005','7',20)

select SUM(c_point) from @tbl1
select SUM(c_point) from @tbl1 where a_goods='001'
select SUM(c_point) from @tbl1 where a_goods='002'
select SUM(c_point) from @tbl1 where a_goods='003'
select SUM(c_point) from @tbl1 where a_goods='004'
select SUM(c_point) from @tbl1 where a_goods='005'
select a_goods, SUM(c_point) from @tbl1 group by a_goods  --商品ごとの平均点

select distinct b_empNo, SUM(c_point) over (partition by b_empNo) from @tbl1  --社員ごとの平均点 
select b_empNo, SUM(c_point) from @tbl1 group by b_empNo  --社員ごとの平均点

以上、SQL Server で SUM関数を使い合計値を求めるでした。

SQL Server AVG 平均

AVG 平均

SQL Server の対象データの平均値の求めるときに、AVG関数を使います。

平均値はいろいろなデータ分析で使用されるので良く使う指標だと思います。

構文: AVG ( [ ALL | DISTINCT ] expression )
引数: ALL すべての値に集計関数が適用されます。 ALL が既定値です。
    DISTINCT 一意な値の合計を返すことを指定します。
expression 定数、列、関数、および算術演算子、ビット演算子、文字列演算子の組み合わせを指定します。
NULL 値はすべて無視されます。(対象データになりません)

下のSQL例文を載せておきます。

declare @tbl1 table(a_class varchar(3), b_kbn char(1), c_point int)
insert into @tbl1 (a_class,b_kbn,c_point) values ('001','1',80)
insert into @tbl1 (a_class,b_kbn,c_point) values ('001','2',60)
insert into @tbl1 (a_class,b_kbn,c_point) values ('001','3',40)
insert into @tbl1 (a_class,b_kbn,c_point) values ('001','4',30)
insert into @tbl1 (a_class,b_kbn,c_point) values ('001','5',50)
insert into @tbl1 (a_class,b_kbn,c_point) values ('001','6',60)
insert into @tbl1 (a_class,b_kbn,c_point) values ('001','7',22)

--ALL
select AVG(ALL c_point) from @tbl1
select AVG(c_point) from @tbl1 --ALLが無くても同じ結果

--DISTINCT
--60が2行あるため、重複を省き計算される
select AVG(DISTINCT c_point) from @tbl1

--expression
--型変換、小数点以下も求める
select AVG(cast(c_point as float)) from @tbl1 --float型に
select AVG(cast(c_point as decimal(5,2))) from @tbl1
select cast(AVG(cast(c_point as decimal(5,2))) as decimal(5,2)) from @tbl1

もう一例
over や group by 句で括って結果を求める

declare @tbl1 table(a_class varchar(5), b_stdNo char(1), c_point int)
insert into @tbl1 (a_class,b_stdNo,c_point) values ('国語','1',60)
insert into @tbl1 (a_class,b_stdNo,c_point) values ('国語','2',70)
insert into @tbl1 (a_class,b_stdNo,c_point) values ('国語','3',40)
insert into @tbl1 (a_class,b_stdNo,c_point) values ('国語','4',20)
insert into @tbl1 (a_class,b_stdNo,c_point) values ('国語','5',40)
insert into @tbl1 (a_class,b_stdNo,c_point) values ('国語','6',50)
insert into @tbl1 (a_class,b_stdNo,c_point) values ('国語','7',20)

insert into @tbl1 (a_class,b_stdNo,c_point) values ('算数','1',70)
insert into @tbl1 (a_class,b_stdNo,c_point) values ('算数','2',60)
insert into @tbl1 (a_class,b_stdNo,c_point) values ('算数','3',50)
insert into @tbl1 (a_class,b_stdNo,c_point) values ('算数','4',80)
insert into @tbl1 (a_class,b_stdNo,c_point) values ('算数','5',30)
insert into @tbl1 (a_class,b_stdNo,c_point) values ('算数','6',60)
insert into @tbl1 (a_class,b_stdNo,c_point) values ('算数','7',40)

insert into @tbl1 (a_class,b_stdNo,c_point) values ('理科','1',90)
insert into @tbl1 (a_class,b_stdNo,c_point) values ('理科','2',70)
insert into @tbl1 (a_class,b_stdNo,c_point) values ('理科','3',40)
insert into @tbl1 (a_class,b_stdNo,c_point) values ('理科','4',70)
insert into @tbl1 (a_class,b_stdNo,c_point) values ('理科','5',60)
insert into @tbl1 (a_class,b_stdNo,c_point) values ('理科','6',50)
insert into @tbl1 (a_class,b_stdNo,c_point) values ('理科','7',50)

insert into @tbl1 (a_class,b_stdNo,c_point) values ('社会','1',30)
insert into @tbl1 (a_class,b_stdNo,c_point) values ('社会','2',50)
insert into @tbl1 (a_class,b_stdNo,c_point) values ('社会','3',90)
insert into @tbl1 (a_class,b_stdNo,c_point) values ('社会','4',40)
insert into @tbl1 (a_class,b_stdNo,c_point) values ('社会','5',70)
insert into @tbl1 (a_class,b_stdNo,c_point) values ('社会','6',80)
insert into @tbl1 (a_class,b_stdNo,c_point) values ('社会','7',30)

insert into @tbl1 (a_class,b_stdNo,c_point) values ('英語','1',80)
insert into @tbl1 (a_class,b_stdNo,c_point) values ('英語','2',60)
insert into @tbl1 (a_class,b_stdNo,c_point) values ('英語','3',40)
insert into @tbl1 (a_class,b_stdNo,c_point) values ('英語','4',30)
insert into @tbl1 (a_class,b_stdNo,c_point) values ('英語','5',50)
insert into @tbl1 (a_class,b_stdNo,c_point) values ('英語','6',60)
insert into @tbl1 (a_class,b_stdNo,c_point) values ('英語','7',20)

select avg(c_point) from @tbl1
select avg(c_point) from @tbl1 where a_class='国語'
select avg(c_point) from @tbl1 where a_class='算数'
select avg(c_point) from @tbl1 where a_class='理科'
select avg(c_point) from @tbl1 where a_class='社会'
select avg(c_point) from @tbl1 where a_class='英語'
select a_class, avg(c_point) from @tbl1 group by a_class  --科目ごとの平均点

select distinct b_stdNo, AVG(c_point) over (partition by b_stdNo) from @tbl1  --生徒ごとの平均点 
select b_stdNo, AVG(c_point) from @tbl1 group by b_stdNo  --生徒ごとの平均点

以上、SQL Server で AVG関数を使い平均値を求めるでした。

SQL Server トランザクション

トランザクション

トランザクション(transaction)とは、不整合を起こさせないための一連の操作の集合のことで、一連の操作全体が一つの単位とみなされます。
複数のSQLを発行してデータ操作をしても、トランザクションを正常に終了させないと、全くデータ操作をしなかったのと同じになるようにされています。

新幹線のチケット販売を考えたとき、支払と切符の販売はセットであり、片方だけでは不都合が起こることから、支払と販売はトランザクション管理されないといけないことが容易に想像できると思います。

トランザクションの開始

SQL Server でトランザクション処理を開始するには、’bigin tran’句を発行します。
トランザクションは’bigin tran tran名’と言うようにトランザクション名を付けることができます。
トランザクション名は 32 文字まで有効です。(超えた分は切り捨てられます)

SQL Server は分散処理もできるため、トランザクションを分散トランザクションとしても実行できます。
その他、マークを付けたりもできます。
また、おかしなことを言うようですが、ネストもできます。複雑なデータ操作だと必要になることあるそうです。
高度なトランザクション管理を行いたい場合は、より深く調査をしてください。

一般的な一連の操作で済む処置であれば(ほとんどがそうなると思うのですが。。。)、以下のように発行してください。


BEGIN TRAN T1

トランザクション終了

トランザクションを終了させるには、’commit’句を発行します。


COMMIT TRAN T1

トランザクションを中断する

何らかのトラブルがあり、トランザクションを中断させ、データ操作を無かったことにしたい場合に’rollback’句を発行します。
プログラムの中だとエラーハンドリンして、その中でロールバックさせるのが一般的です。


rollback

以下に簡単なトランザクションの例を載せておきます。

正常に終了するパターン:

create table tbl1 (a_cd nvarchar(9))
create table tbl2 (a_cd nvarchar(9))

declare @acd nvarchar(9)
set @acd='00001'

begin tran t1

begin try

  insert into tbl1 (a_cd) values (@acd)
  insert into tbl2 (a_cd) values (@acd)

  commit tran t1

end try
begin catch

  rollback

end catch

select * from tbl1
select * from tbl2

-----後処理
drop table tbl1
drop table tbl2

set @acd=1/0を入れエラーを起こさせたパターン:

create table tbl1 (a_cd nvarchar(9))
create table tbl2 (a_cd nvarchar(9))

declare @acd nvarchar(9)
set @acd='00001'

begin tran t1

begin try

  insert into tbl1 (a_cd) values (@acd)
  insert into tbl2 (a_cd) values (@acd)
  set @acd=1/0

  commit tran t1

end try
begin catch

  rollback

end catch

select * from tbl1
select * from tbl2

-----後処理
drop table tbl1
drop table tbl2

動かしてみるとわかりますが、rollbackも含め正常にトランザクション処理されています。

なお、テーブル変数を使うと、テーブル変数は持続性のあるデータベースの一部ではないため、トランザクションのロールバックによる影響を受けません。
ロールバックしてもデータは途中までの操作が有効になったままなので、トランザクション処理を行う時は要注意です。

以上、トランザクションの簡単な説明でした。