こんにちは、ねこです。

自称プログラマのおばちゃんのブログです。いろいろあるよねぇ~。

Microsoft MCSA SQL Server 2016 (70-761) むぼーな挑戦 4

2019-10-31 07:23:39 | プログラム 勉強

どこかの有名youtuberが、「朝が一番賢い時間です」と書いてあったので、今7:15、掃除、家事せずに8時半ごろまで勉強することにしました。

1.読み落とし

パターン1

『Each Transact-SQL segment may be used once, more than once, or not at all.

何回使ってもいいって。。。泣けてくるぜ。

…って、まてよ!これまちがってませんか?

『WHERE』じゃなくて『HAVING』じゃないの?


(参照SamuraiBlogさま ありがとうございます。)

『「WHERE」も「HAING」と同じく「抽出条件を指定」するコマンドでのです。つまり、先ほどの処理は「WHERE」で書いても全く同じ結果が返ってくるんです。』

SELECT文を使用した時の、命令の呼ばれる順番です。

今回の主役である「WHERE」と「HAVING」は画像の通り「WHERE」→「GROUP BY」→「HAVING」の順に呼ばれるわけです。つまり間にある「GROUP BY」が関わってこなければ、全く同じ挙動をしますが、
「GROUP BY」を使って、グループ化を行った際には、以下の違いが出てくるわけです。


では、この場合をみてみましょう!

『WHERE COUNT(Cust.CustomerId) > 5』

そして、『Group By』は『Cust.CustomerId』コラムがふくまれてない。

『CustCat.CustomerCategoryName』と『CustAccountOpenedDate』でグループされてますよ!

とういことは、『HAVING』は使えない!!!

はぁ~、そういうことか。。。

 

4.ふたを開けたらわかってなかった

Note: This question is part of a series of questions that use the same scenario. For your convenience, the scenario is repeated in each question. Each question presents a different goal and answer choices, but the text of the scenario is exactly the same in each question on this series.

You have a database that tracks orders and deliveries for customers in North America. System versioning is enabled for all tables. The database contains the
Sales.Customers, Application.Cities, and Sales.CustomerCategories tables.
Details for the Sales.Customers table are shown in the following table:

Details for the Application.Cities table are shown in the following table:

Details for the Application.Cities table are shown in the following table:

Details for the Sales.CustomerCategories table are shown in the following table:



パターン1

複数選択式
A.
B.
C.
D.
あきらかに、CとDは違う。Aも『CROSS JOIN』だから、CartesianProduct(直積集合)になってしまいます。
なので答えはA。
ちょーとまったあっ!
 
WHERE (IsOnCreditHold = 0 AND DeliveryCityID = CityID)
OR (IsOnCreditHOld = 1 AND PostalCityID = CityyID)
 
とあります。ちゃんとよんだかぁ!
『You need to create a query that meets the following requirements:
-> For customers that are not on a credit hold, return the CustomerID and the latest recorded population for the delivery city that is associated with the customer.
-> For customers that are on a credit hold, return the CustomerID and the latest recorded population for the postal city that is associated with the customer.』
これで、しっかりコンディションが網羅されてるから、『CROSS JOIN』でも大丈夫です。
<答え>A,B
 
 

パターン2

You discover an application bug that impacts customer data for records created on or after January 1, 2014. In order to fix the data impacted by the bug, application programmers require a report that contains customer data as it existed on December 31, 2013.
You need to provide the query for the report.

A.
B.
C.
D.
E.
さてと、まずは『an application bug that impacts customer data for records created on or after January 1, 2014』
ふむふむ。(2014,1,1)にバグがあったんだな。
programmers require a report that contains customer data as it existed on December 31, 2013
おっと、ここが本当に聞いてきているぶぶんだ、だから最初の(2014,1,1)はデコイ、ひっかけです。
<E>
すると、Eは『@date』が二つも出てきて比べてるんで、完全に間違い。
 
<D>
Dは『@date』が(2013,12,31)のままで変わってないし、『BETWEEN』は以下を確認。
SELECT * FROM employees WHERE start_date BETWEEN '2013,12,31' AND '2014,01,01';
SELECT * FROM employees WHERE start_date >= '2013,12,31' AND start_date <= '2014,01,01';
同じです。
 ということなので、『programmers require a report that contains customer data as it existed on December 31, 2013』の部分でDecember 31, 2013(2013,12,31)の日だけ聞いているから、両日を含む『BETWEEN』は間違え。
<C>
Cは『SYSTEM_TIME AS OF』をよく覚えてないけど、December 31, 2013(2013,12,31)の日を聞いてないから、外す。いえいえ、この日の結果をしりたいんです!
<B>
Bは『DATEADD(d, -1, @sdate)』で、December 31, 2013(2013,12,31)の前の日を当ててるから、完全にアウト。
<A>
Aは@sdate = December 31, 2013(2013,12,31)、@edateとあって、『DATEADD(d, 1, sdate)』でJanuary 1, 2014(2014,01,01)を設定してるんだよね。でも
『WHERE ValidFrom >@sdate AND ValidTo < @edate』
 = 『WHERE ValidFrom >December 31, 2013(2013,12,31) AND ValidTo < January 1, 2014(2014,01,01)』
となってるから、あれっ?どっちの日も含まれてないことになってるじゃん!!!
一体どれなんや。。。
 
 
『SYSTEM_TIME AS OF』
はい。一番怪しい『SYSTEM_TIME AS OF』を調べます。
もし、‘2015-12-29 07:51’のデータが欲しい場合は、
SELECT Id, Name, StartTime, EndTime
FROM dbo.Customer
FOR SYSTEM_TIME AS OF '2015-12-29 07:51'
これは
StartTime<= @PointInTime AND EndTime > @PointInTime

と同じになります。
FOR SYSTEM_TIME AS OF TimeLine Graph
 
 
FOR SYSTEM_TIME AS OF Example 1
 
そして、もしこの『SYSTEM_TIME AS OF』を使わずにクエリをつくると、
DECLARE @PointInTime DATETIME = '2015-12-29 07:51'
SELECT Id, Name, StartTime, EndTime
FROM dbo.Customer
WHERE StartTime<= @PointInTime  AND EndTime > @PointInTime 
UNION ALL
SELECT Id, Name, StartTime, EndTime
FROM dbo.CustomerHistory
WHERE StartTime<= @PointInTime  AND EndTime > @PointInTime 

となり、『Temporal Table』と『History Table』を『UNION ALL』で比べて結果を出すことになります。

まだよーわからんのですが、とにかく『StartTime<=@PintInTime』という部分がみそなんでしょうね。だから、『BETWEEN』は使えないのね。

<結果>
Equivalent of FOR SYSTEM_TIME AS OF

 <答え>C

ここにある問題は過去問と全く同じですね。

さぁ、掃除しよう。全然答えられなかったから、なんかモヤモヤするなぁ。

 
 

最新の画像もっと見る

コメントを投稿