letcode: 595.大的国家

有一个World表

  1. +-----------------+------------+------------+--------------+---------------+
  2. | name | continent | area | population | gdp |
  3. +-----------------+------------+------------+--------------+---------------+
  4. | Afghanistan | Asia | 652230 | 25500100 | 20343000 |
  5. | Albania | Europe | 28748 | 2831741 | 12960000 |
  6. | Algeria | Africa | 2381741 | 37100000 | 188681000 |
  7. | Andorra | Europe | 468 | 78115 | 3712000 |
  8. | Angola | Africa | 1246700 | 20609294 | 100990000 |
  9. +-----------------+------------+------------+--------------+---------------+

如果一个国家的面积超过300万平方公里,或者人口超过2500万,那么这个国家就是大国家。

编写一个SQL查询,输出表中所有大国家的名称、人口和面积。

例如,根据上表,我们应该输出:

+--------------+-------------+--------------+
| name         | population  | area         |
+--------------+-------------+--------------+
| Afghanistan  | 25500100    | 652230       |
| Algeria      | 37100000    | 2381741      |
+--------------+-------------+--------------+

解决思路:一开始的思路就是查询World表。用Where条件去筛选国家面积超过300万平方公里,或者人口超过2500万,使用OR关键字来判断这两个条件
重点是OR关键字,只要一个条件成立就可以查询出来。
具体SQL:

select name ,population, area from World where area > 3000000 or population > 25000000

后来查看别人代码,基本都是这种写法。主要就是OR关键字、。

MySQL OR短路求值

MySQL OR运算符组合了两个或两个以上布尔表达式。当任一条件为真时,返回true
MySQL使用OR运算符进行短路评估(求值计算)。 换句话说,当MySQL可以确定结果时,MySQL会停止评估(求值计算)语句的其余部分。
例如如下SELECT代码

SELECT 1 = 1 OR 1 / 0;

因为表达式1 = 1总是返回true,MySQL不会对1/0进行求值。如果是这样,它会发出一个除以零错误的错误消息。

运算符优先级

语句中使用多个逻辑运算符时,MySQL会在AND运算符之后再对OR运算符进行求值。 这称为运算符优先级。
运算符优先级决定运算符的求值顺序。 MySQL首先对优先级较高的运算符进
行求值。

SELECT true OR false AND false;

运行结果是:1

  • 首先,MySQL对AND运算符求值,因此,false AND false返回false

  • 其次,MySQL对OR运算符求值,根据返回的false值再执行AND运算,因此true OR false返回true

要更改评估/求值的顺序,请使用括号
例如:

SELECT (true OR false) AND false;

运行结果是:0

LETCODE 182. 查找重复邮箱

编写一个 SQL 查询,查找 Person 表中所有重复的电子邮箱。

示例:

+----+---------+
| Id | Email   |
+----+---------+
| 1  | a@b.com |
| 2  | c@d.com |
| 3  | a@b.com |
+----+---------+

根据以上输入,你的查询应返回以下结果:

+---------+
| Email   |
+---------+
| a@b.com |
+---------+

说明:所有电子邮箱都是小写字母。
解决思路:一开始就是想着查询出来邮箱数量大于等于2的记录
,然后去重,后来发现别人提交的记录都是使用分组之后判断邮箱个数大于1查询

我的SQL:select DISTINCT(Email) from Person p1 where (select count(*) from Person p2 where p2.Email = p1.Email ) >= 2

后来查看别人的代码:

方法一:使用 GROUP BY 和临时表

select Email from
(
  select Email, count(Email) as num
  from Person
  group by Email
) as statistic
where num > 1

方法二:使用 GROUP BYHAVING 条件

select Email
from Person
group by Email
having count(Email) > 1;

LOWER(str):

lower():返回字符串str根据当前字符集映射转为小写字母。

627.交换工资

给定一个 salary表,如下所示,有m=男性 和 f=女性的值 。交换所有的 f 和 m 值(例如,将所有 f 值更改为 m,反之亦然)。要求使用一个更新查询,并且没有中间临时表。
使用一个更新查询,并且没有中间临时表。

例如:

| id | name | sex | salary |
|----|------|-----|--------|
| 1  | A    | m   | 2500   |
| 2  | B    | f   | 1500   |
| 3  | C    | m   | 5500   |
| 4  | D    | f   | 500    |

运行你所编写的查询语句之后,将会得到以下表:

| id | name | sex | salary |
|----|------|-----|--------|
| 1  | A    | f   | 2500   |
| 2  | B    | m   | 1500   |
| 3  | C    | f   | 5500   |
| 4  | D    | m   | 500    |

解决思路:判断性别的值,将sex为f改成m,反之亦然。
Mysql的if既可以作为表达式用,也可在存储过程中作为流程控制语句使用

IF表达式

IF(expr1,expr2,expr3)
1
如果 expr1 是TRUE (expr1 <> 0 and expr1 <> NULL),则 IF()的返回值为expr2; 否则返回值则为 expr3。IF() 的返回值为数字值或字符串值,具体情况视其所在语境而定。

我的SQL:UPDATE salary SET sex = IF(sex = 'm','f','m') where sex IS NOT NULL

后来查看别人代码使用CASE WHEN 语句做的:

示例1:update salary set sex =case when sex = 'f' then 'm'else 'f'end
示例2:
update salary
set sex=(case when sex='f' then 'm'
              when sex='m' then 'f'
         end)

SQL中的CASE WHEN 语句

具体详见博客 SQL中CASE WHEN 的 语法:https://www.cnblogs.com/qiantuwuliang/archive/2009/06/03/1495770.html