SQLバックルの練習(8)

目次

1. 少なくとも 5 人の直属の部下を持つマネージャー (570)

方法 1 (で)

方法2(結合)

方法 3 (行番号)

方法 4 (自己結合)

2. スタッフボーナス(577)

方法 1 (左結合)

3. ユーザーの紹介を募集しています (584)

方法 1

4. 2016 年の投資 (585)

方法 1 (結合、カウント)

方法 2 (インチ)

方法 4 (接続プラスイン)


1. 少なくとも 5 人の直属の部下を持つマネージャー (570)

表面: Employee

+-------------+--------+ 
| 列名 | タイプ | 
+-------------+---- ---+ 
| id | int | 
| 名前 | varchar | 
| 部門 | varchar | 
| managerId | int | 
+-------------+--------- + 
SQLでは、idはテーブルの主キー列です。
このテーブルの各行は、従業員の名前、部門、およびマネージャーの ID を表します。
managerId が空の場合、従業員にはマネージャーがいません。
従業員が自分自身のマネージャーになることはありません。

少なくとも 5 人の直属の部下を持つクエリマネージャー 

結果テーブルを任意の順序 で 返します

方法 1 (で)

まず同じボスの少なくとも 5 つの ID を見つけてから探します。

# Write your MySQL query statement below
select name from employee where id in
(select managerId from employee 
group by managerId having count(*)>=5 )

方法2(結合)

まず適切なマネージャー ID を見つけてから接続に参加します。これは方法 1 よりも高速です。

# Write your MySQL query statement below
select name from employee e join
(select managerId from employee 
group by managerId having count(*)>=5) temp 
on e.id=temp.managerId

方法 3 (行番号)

row_number を使用して同じボスを並べ替え、ボス ID をフィルタリングしてから自己接続します。この方法は時間がかかるため、お勧めできません。

# # Write your MySQL query statement below

select name from employee a join 
    (select managerId from 
        (select managerId,(ROW_NUMBER() over (partition by managerId order by id)) num 
    from employee ) e 
group by e.managerId having max(e.num)>=5)
b on a.id=b.managerId

方法 4 (自己結合)

自己接続、このアイデアは非常に良いです。2 番目の方法とこの方法をお勧めします。

    SELECT
        e1. NAME
    FROM
        Employee AS e1
    JOIN Employee AS e2 ON (e1.id = e2.managerid)
    GROUP BY
        e1.id
    HAVING
        count(e1.id) >= 5

2. スタッフボーナス(577)

ボーナスが 1000 未満の全従業員の名前とボーナスを選択します。

Employee 形状

+----------+--------+---------------+----------+ 
| empId | 名前 | 上司| 給与 | 
+- -------+----------+----------+----------+ 
| 1 | ジョン | 3 | 1000 | 
| 2 | | 3 | 2000 | 
| 3 | ブラッド | null | 4000 | 
| 4 | トーマス | 3 | 4000 | 
+-------+-------+--------- -- +----------+ 
empId はこのフォームの主キーです

Bonus 形状

+------+-------+ 
| empId | ボーナス | 
+-------+-------+ 
| 2 | 500 | 
| 4 | 2000 | 
+ -------+------+ 
empId はこのフォームの主キーです

出力例:

+------+-------+ 
| 名前 | ボーナス | 
+------+-------+ 
| ジョン | ヌル | 
| ダン | 500 | 
| ブラッド | ヌル | 
+-----+------+

方法 1 (左結合)

ここで、ボーナスが空になる可能性があることに注意してください。

# Write your MySQL query statement below
select e.name,b.bonus 
from employee e left join bonus b 
on b.empId=e.empId 
where b.bonus<1000 or b.bonus is null

3. ユーザーの紹介を募集しています (584)

すべての顧客情報とその参照者を保持するテーブルがあるとします customer 。

+------+------+-----------+ 
| ID | 名前 | 審判者ID| 
+------+------+-----------+ 
| 1 | ウィル | NULL | 
| 2 | ジェーン | NULL | 
| 3 | アレックス | 2 | 
| 4 | ビル | NULL | 
| 5 | ザック | 1 | 
| 6 | マーク | 2 | 
+------+------+----------+

参照者番号が 2 ではない 

上記のデータ例の場合、結果は次のようになります。

+------+ 
| 名前 | 
+------+ 
| ウィル | 
| ジェーン | 
| ビル | 
| ザック | 
+-----+

方法 1

簡単なので説明は不要

# Write your MySQL query statement below
select name from customer 
where referee_id != 2 or referee_id is null

4. 2016 年の投資 (585)

Insurance 表面:

+-------------+----------+ 
| 列名 | タイプ | 
+-------------+------ -+ 
| pid | int | 
| tiv_2015 | float | 
| tiv_2016 | float | 
| lat | float | 
| lon | float | 
+-------------+----------+ 
pid はこのテーブルの主キーです。
テーブルの各行には保険情報が含まれています。
pid は保険契約者の保険番号です。
tiv_2015 は 2015 年の契約者の保険金額の合計、tiv_2016 は 2016 年の契約者の保険金額の合計です。
lat は保険契約者の都市の緯度です。トピック データにより、lat が空でないことが保証されます。
lon は保険契約者の都市の経度です。タイトル データにより、lon が空でないことが保証されます。

2016 年に次の条件を満たすすべての保険契約者の保険金額の合計を報告する SQL クエリを作成してください ( ) tiv_2016:

  • 彼の 2015 年の保険金額 ( tiv_2015) は、少なくとも 1 人の他の保険契約者の 2015 年の保険金額と少なくとも同じでした。
  • 彼の都市は他の保険契約者とは異なる必要があります (つまり、( lat, lon) は他の保険契約者とまったく同じであってはなりません)。

tiv_2016小数点以下第 2 位 に四捨五入  。

クエリ結果の形式を次の例に示します。

入力:
保険テーブル: 
+-----+----------+----------+-----+-----+ 
| pid | tiv_2015 | tiv_2016 | 緯度 | 経度 | 
+-----+----------+----------+-----+-----+ 
| 1 10 | 5 | 10 | 10 | 
| 2 | 20 | 20 | 20 | 20 | 
| 3 | 10 | 30 | 20 | 20 | 
| 4 | 10 | 40 | 40 | 40 | 
+-----+- - --------+----------+-----+-----+出力: 
+----------+ 
| tiv_2016 | 
+ ----------+ 
| 45.00 | 
+----------+説明:
テーブルの最初のレコードと最後のレコードは両方とも 2 つの条件を満たしています。
tiv_2015 値 10 は 3 番目と 4 番目のレコードと同じであり、それらの位置は一意です。
2 番目のレコードはどちらの条件も満たしません。その tiv_2015 は他の保険契約者とは異なり、その場所は 3 番目のレコードと同じであるため、3 番目のレコードはタイトル要件を満たしていません。


したがって、結果は最初と最後のレコードの tiv_2016 の合計、つまり 45 になります。

方法 1 (結合、カウント)

まず条件 1 と条件 2 をそれぞれクエリしてから、クエリを接続します。

条件一:

count(*)>=2 を持つ tiv_2015 によって保険グループから tiv_2015 を選択します

条件二:

count(*)=1 の緯度経度による保険グループから * を選択します

# Write your MySQL query statement below

select round(sum(a.tiv_2016),2) tiv_2016 from
# 他在 2015 年的投保额 (tiv_2015) 至少跟一个其他投保人在 2015 年的投保额相同
(select * from insurance group by lat,lon having count(*)=1) a join
# 他在 2015 年的投保额 (tiv_2015) 至少跟一个其他投保人在 2015 年的投保额相同。
(select tiv_2015 from insurance group by tiv_2015 having count(*)>=2) b
on a.tiv_2015=b.tiv_2015

方法 2 (インチ)

concat() 関数は、2 つの文字列を連結して 1 つの文字列を形成するために使用されます。


select round(sum(tiv_2016), 2) tiv_2016 from insurance 
where tiv_2015 in (
	select tiv_2015 from insurance group by tiv_2015 having count(*) > 1
) and concat(lat, lon) in (
	select concat(lat, lon) from insurance group by lat, lon having count(*) = 1
);

方法3(カウント)

カウント ウィンドウ関数を使用する場合、考え方は方法 1 と似ています。

select round(sum(tiv_2016), 2) tiv_2016 from (
	select
		tiv_2016,
		count(*) over(partition by tiv_2015) count_tiv_2015,
		count(*) over(partition by lat, lon) count_lat_lon
	from insurance
) as temp where count_lat_lon = 1 and count_tiv_2015 > 1

方法 4 (接続プラスイン)

最初に self-connection を使用して条件 1 を満たし、次に not in を使用して条件 2 を満たします。

# Write your MySQL query statement below
select round(sum(distinct o1.TIV_2016), 2) tiv_2016
from insurance o1 inner join insurance o2 
on o1.PID != o2.PID and o1.TIV_2015 = o2.TIV_2015
where (o1.LAT,o1.lon) not in 
    (select lat, lon from insurance where o1.PID != PID)

おすすめ

転載: blog.csdn.net/weixin_53011574/article/details/131978330