Oracle学习(四) --- DQL语法

标准DQL语法

select distinct * | 列名 as 别名, 列表2 as 别名2... | 聚合函数
from 表名 as 别名, 表名2 as 别名2 ,....
where 查询条件
group by 分组字段 having 分组条件
order by 排序字段 asc | desc,....

1、查询 -- 单表查询

1.1、简单查询练习

-- 1 查询水表编号为30408的业主记录
select * from t_owners where watermeter = '30408';
--  使用表的别名
select * from t_owners ow where ow.watermeter = '30408';


-- 2 查询业主名称包含“刘”的业主记录
--- like 语句  %匹配多个字符  _匹配1个字段
select * from t_owners where name like '%刘%';

-- 3 查询业主名称包含“刘”的并且门牌号包含5的业主记录
select * from t_owners where name like '%刘%' and housenumber like '%5%';

-- 4 查询业主名称包含“刘”的或者门牌号包含5的业主记录
select * from t_owners where name like '%刘%' or housenumber like '%5%';

-- 5 查询业主名称包含“刘”的或者门牌号包含5的业主记录,并且地址编号为3的记录。
--- and 优先级 高于 or,如果先执行or,需要使用小括号
select * from t_owners where (name like '%刘%' or housenumber like '%5%') and addressid = 3;

-- 6 查询台账记录中用水字数大于等于10000,并且小于等于20000的记录
--- 关系运算符: > >= < <= == <>
select * from t_account where usenum >= 10000 and usenum <= 20000;
--- 字段 between ... and ...
select * from t_account where usenum between 10000 and 20000;

-- 7 查询T_PRICETABLE表中MAXNUM为空的记录
select * from t_pricetable where maxnum is null;

-- 8 查询T_PRICETABLE表中MAXNUM不为空的记录
select * from t_pricetable where maxnum is not null;

1.2、去重复和排序

-- 去重复
-- 需求:查询业主表中的地址ID,不重复显示
select distinct addressid from t_owners;
select distinct(addressid) from t_owners;

-- 排序
-- select ... order by 字段 asc|desc ,字段2 asc|desc,....
--需求:对T_ACCOUNT表按使用量进行升序排序
select * from t_account order by usenum asc

--需求:对T_ACCOUNT表按使用量进行降序排序
select * from t_account order by usenum desc

--需求:对T_ACCOUNT表 按照month降序,如果相同按照usenum进行升序
select * from t_account order by month desc , usenum asc ;

1.3、伪列

  • 伪劣是oracle中独有的,伪劣也是真实存在的列,用于查询操作,不能增删改操作。
常见伪列描述
rowid物理文件上唯一区别记录的唯一标识 <br>用途:用于区分重复数据
rownum在查询的结果集中,ROWNUM为结果集中每一行标识一个行号<br>用途:在Oracle进行分页
  • rowid

    • 在mysql表中存在数据相同记录,如果对某一条进行操作,讲修改所有的数据。

  • Oracle使用rowid区别每一条数据,不会存在操作一条,影响多条的情况。

  • rownum

    -- 查询
    select rownum,t_account.* from t_account;
    

1.4、聚合函数

  • ORACLE的聚合统计是通过分组函数来实现的,与MYSQL一致。
  • 聚合函数:通过提供函数,讲查询结果处理成一行一列数据。
    • 特点:聚合函数不计算null值
聚合函数描述
sum求和
avg平均
max最大值
min最小值
count计数
-- 聚合函数
--1 统计2012年所有用户的用水量总和
select sum(usenum) from t_account where year = '2012';

--2 统计2012年所有用水量(字数)的平均值
insert into t_account values( seq_account.nextval,2,1,3,'2012','12',95076,99324,null,1,sysdate,44.51,'1',to_date('2014-01-14','yyyy-MM-dd'),2 );
select avg(usenum) from t_account where year = '2012';

--3 统计2012年最高用水量(字数)
select max(usenum) from t_account;

--4 统计2012年最低用水量(字数)
select min(usenum) from t_account;

--5 统计记录个数 count
select count(id) from t_account;

2、查询 -- 连接查询

  • 笛卡尔积:两个表乘积,所有的数据最大集(开发无用)

    select * from A , B;
    
  • 内连接

    • 隐式内连接

      select * from A , B where a.id = b.id
      
    • 显示内连接

      select * from A inner join B a.id = b.aid
      
  • 外连接

    • 左外连接:查询左表(A)所有数据,如果条件成立显示右边(B)的数据,否则显示null

      select * from A left outer join B on a.id = b.aid
      
    • 右外连接:查询右表(B)所有数据,如果条件成立显示左边(A)的数据,否则显示null

      select * from A right outer join B on a.id = b.aid
      

2.1、内连接查询练习

--连接查询
-- 1查询显示业主编号,业主名称,业主类型名称
--- 隐式内连接
select ow.id,ow.name,ot.name from t_owners ow , t_ownertype ot 
where ow.ownertypeid = ot.id;
--- 显示内连接
select ow.id,ow.name,ot.name from t_owners ow
inner join t_ownertype ot on ow.ownertypeid = ot.id;

-- 2查询显示业主编号,业主名称、地址和业主类型
--- 隐式内连接
select ow.id,ow.name,ad.name,ot.name from t_owners ow , t_ownertype ot , t_address ad
where ow.ownertypeid = ot.id and ow.addressid = ad.id;
select ow.id,ow.name as 业主名称,ad.name 地址名称,ot.name 业主类型名称 from t_owners ow , t_ownertype ot , t_address ad
where ow.ownertypeid = ot.id and ow.addressid = ad.id;
--- 显示内连接
select ow.id,ow.name,ad.name,ot.name from t_owners ow 
inner join t_address ad on ow.addressid = ad.id
inner join t_ownertype ot on ow.ownertypeid = ot.id;

-- 3查询显示业主编号、业主名称、地址、所属区域、业主分类
--- 隐式内连接
select ow.id,ow.name 业主名称,ad.name 地址,ar.name 所属区域,ot.name 业主分类 from t_owners ow , t_ownertype ot , t_address ad , t_area ar 
where ow.ownertypeid = ot.id and ow.addressid = ad.id and ad.areaid = ar.id
--- 显示内连接
select ow.id,ow.name 业主名称,ad.name 地址,ar.name 所属区域,ot.name 业主分类 from t_owners ow
inner join t_ownertype ot on ow.ownertypeid = ot.id
inner join t_address ad on ow.addressid = ad.id 
inner join t_area ar on ad.areaid = ar.id;

2.2、左外连接

-- 左外链接
--需求:查询业主的账务记录,显示业主编号、名称、年、月、金额。如果此业主没有账务记录也要列出姓名。
select ow.id,ow.name,ac.year,ac.month,ac.money from t_owners ow
left outer join t_account ac on ow.id = ac.ownerid 

2.3、右外连接

--需求:查询业主的账务记录,显示业主编号、名称、年、月、金额。如果账务记录没有对应的业主信息也要列出记录。
--- 准备数据,修改将 t_account 表 ownerid 非空约束去掉
insert into t_account values( seq_account.nextval,null,1,3,'2012','12',95076,99324,0,1,sysdate,44.51,'1',to_date('2014-01-14','yyyy-MM-dd'),2 );

select ow.id,ow.name,ac.year,ac.month,ac.money from t_owners ow right outer join t_account ac on ow.id = ac.ownerid

2.4、Oracle左外连接特殊用法(了解)

  • 在内连接基础上,使用(+) 转换 左外连接
-- Oracle 班级簿左外连接
select ow.id,ow.name,ac.year, ac.month ,ac.money from t_owners ow , t_account ac where ow.id = ac.ownerid (+);
  • 用法:

    • 左外连接:在连接条件处,右表条件字段添加(+)

3、子查询

3.1、概述

  • 子查询:一个select语句,作为另一条select语句语法的一部分。

  • select语句语法:

    select distinct * | 字段 from 表名
    where 查询条件
    group by 分组字段 having 分组条件
    order by 排序字段 asc | desc
    

3.2、单行子查询

  • 编写步骤,将一个需求拆分成多个子需求,依次完成每一个子需求,最后将组合子需求
-- 查询2012年1月用水量大于平均值的台账记录
-- 1 用水量平均值
select avg(usenum) from t_account where year='2012' and month = '01'
-- 2 查询2012年1月所有用水量
select * from t_account where year='2012' and month = '01'
-- 3 合并
select * from t_account where year='2012' and month = '01' and usenum > 20009.5
select * from t_account where year='2012' and month = '01' and usenum > (
select avg(usenum) from t_account where year='2012' and month = '01'
)

3.3、多行子查询

--查询2012年台账中,使用量大于2012年3月最大使用量的台账数据
-- 方式1:求最大值
-- 1. 求2012年3月最大使用量
select max(usenum) from t_account where year = '2012' and month = '03'
-- 2. 查询2012年台账 大于 13808
select * from t_account where year = '2012' and usenum > 13808
-- 3. 整合
select * from t_account where year = '2012' and usenum > (
select max(usenum) from t_account where year = '2012' and month = '03')

-- 方式2:使用all运算符
-- 1. 求2012年3月所有使用量
select usenum from t_account where year = '2012' and month = '03'
-- 2. 查询2012年台账 大于 3月所有使用量
select * from t_account where year = '2012' and usenum > all (13808,13390)
-- 3. 整合
select * from t_account where year = '2012' and usenum > all (select usenum from t_account where year = '2012' and month = '03')


3.4、嵌套子查询

  • 嵌套子查询:在子查询中再次嵌入子查询
-- 查询在海淀区的小区名字中含有花园的业主记录
-- 1. 查询区域id,名称为“海淀” --多个海淀
select id from t_area where name = '海淀'
-- 2. 查询地址id,条件:名称含“花园” 和 区域id 
select id from t_address where name like '%花园%' and areaid in (1)
-- 3 组合 1+2
select id from t_address where name like '%花园%' and areaid in (
  select id from t_area where name = '海淀'
)
-- 4. 查询业主,条件:一组地址id
select * from t_owners where addressid in (1)
-- 5. 组合
select * from t_owners where addressid in (
  select id from t_address where name like '%花园%' and areaid in (
    select id from t_area where name = '海淀'
  )
)

--- 只有一个海淀
select id from t_address where name like '%花园%' and areaid = (
  select id from t_area where name = '海淀'
)


3.5、标量子查询

  • 标量子查询:子查询的语句执行的结果直接作为主查询的结果显示
-- 查询台账表中的用户年用水量的总和    以及  年平均用水量
-- 1. 查询用水量总和  137868
select sum(usenum) from t_account
-- 2. 查询用水量平均值 5514.72
select avg(usenum) from t_account
-- 3. 将两个不相关的数据,使用虚表 dual 组合在一起
select (137868) as 总和,(5514.72) as 平均 from dual
select (
  select sum(usenum) from t_account
) as 总和,(
  select avg(usenum) from t_account
) as 平均 from dual

3.6、相关子查询

  • 相关子查询:子查询依赖外面的主查询的结果
练习1:3表练习
-- 查询显示业主编号,业主名称、地址和业主类型
-- 1. 查询业主编号,名称
select id,name,addressid,ownertypeid from t_owners 
-- 2. 根据地址id,查询地址
select name from t_address where id = 1
-- 3. 根据类型id,查询业主类型
select name from t_ownertype where id = 1

-- 4. 组合
select ow.id,ow.name,(
  select name from t_address where id = ow.addressid
) 地址名称 ,ownertypeid from t_owners ow

select ow.id,ow.name,(
  select name from t_address where id = ow.addressid
) 地址名称 ,(
  select name from t_ownertype where id = ow.ownertypeid
) from t_owners ow


练习2:4表练习
-- 查询显示业主编号、业主名称、地址、所属区域、业主分类
-- 1. 查询业主编号,名称
select id,name,addressid,ownertypeid, ar.name from t_owners 
-- 2. 根据地址id,查询地址
select name from t_address where id = 1
-- 3. 根据类型id,查询业主类型
select name from t_ownertype where id = 1
-- 4. 根据区域id,查询区域
select ar.name from t_area ar, t_address ad where ar.id = ad.areaid and ad.id = 1
-- 5 组合

select ow.id, ow.name,(
  select name from t_address where id = ow.addressid
) ,(
  select name from t_ownertype where id = ow.ownertypeid
) , (
  select ar.name from t_area ar, t_address ad where ar.id = ad.areaid and ad.id = ow.addressid
) from t_owners ow


4、分页查询

4.1、概述

  • mysql提供limit语句进行分页
  • Oracle没有提供特定关键字处理分页
  • Oracle分页需要使用:rownum + 子查询

4.2、基本分页

  • 一条select rownum 只能使用 < 和 <= (rownum是在查询语句扫描每条记录时产生)
-- 分页
--- 基本分页
--1.查询所有台账表
select * from t_account;
--2.查询所有台账表,含rownum
select rownum r, a.* from t_account a;
--3.第一页
select rownum, a.* from t_account a where rownum<=10;
--4.第二页 , rownum 在处理每行数据时生产,不能使用大于号>
--select t.* from A t
--where t.r > 10 and t.r <=20
select t.* from(select rownum r,a.* from t_account a)t 
where t.r > 10 and t.r<=20;

4.3、分页 + 排序

  • 需要使用3个select完成此功能

    a.查询所有,并排序

    b.给排好序的结果,添加 rownum

c.对最后结果进行分页条件过滤

--- 排序 + 分页
--1. 查询所有 + 排序
select * from t_account orderby usernum desc;

--2. 结果 --> + rownum
-- select rownum r, t.* from () t
select rownum r,t.* from(
  select * from t_account order by usenum desc
) t;

--3. 结果 --> 分页条件
-- select * from B t2
-- where t2.r > 10 and t2.r <= 20
select * from(
  select rownum r, t.* from(
    select * from t_account order by usenum desc  
  )t
)t2
where t2.r >10 and t2.r <=20;

4.4、Oracle语句执行顺序

1.先扫描每一条记录,并添加 rownum

2.在进行where 条件过滤

3.在进行order by 排序

  • 执行以下语句,已完成rownum 初始化

    select rownum,t.* from t_account t
    

  • rownum 初始化后,再执行 order by
select rownum, t.* from t_account t order by usenum desc

5、单行函数

5.1、字符函数

--- 字符函数
--1 字符串拼接  dual
select concat('abc','d') from dual;
select 'abc' || '123' from dual;

--2 首字母大写:将一个单词首字母转换成大写,其他字母转换成小写
select initcap('HEllo') from dual;

--3 找出字符串位置,从1开始计数
select instr('hello','e') from dual;

--4 字符串长度
select length('abcd') from dual;

--5 替换  repacle(字符串, 被替换内容, 替换内容)
select replace('hello hello','e','x') from dual;

--6 截取字符串 
-- substr('字符串',起始位置) 从‘起始位置’截取到最后
-- substr('字符串',起始位置,长度)
select substr('abcde',2) from dual;
select substr('abcde',2,2) from dual;

--7 去除两端空格
select length(' abcde ') from dual;
select length(trim(' abcde ')) from

--8 转换小写
select lower('hEllo') from dual;

--9 转换大写
select upper('hEllo') from dual;

5.2、数值函数

--- 数值函数
--1 ceil 向上取整
select ceil(12.1) from dual;
select ceil(12.9) from dual;
--2 floor 向下取整
select floor(12.1) from dual;
select floor(12.9) from dual;
--3 round 四舍五入
-- round(数值) 对数值四舍五入,没有小数位
-- round(数值,精度) 保留小数位数进行四舍五入
select round(12.1) from dual;
select round(12.9) from dual;

-- 12.35
select round(12.3456,2) from dual;

--4 取模   10 % 3
select mod(10,3) from dual;

--5 截取
-- 12.34
select trunc(12.3456,2) from dual;

5.3、日期函数

--- 日期函数
--1 当前系统时间
select sysdate from dual;

--2 add_months 添加count个月
select add_months(sysdate,-2) from dual;

--3 last_day 本月最后一天
select last_day(sysdate) from dual;

--4 to_date 将字符串转换日期
select to_date('20200401','yyyymmdd') from dual;
select '20200401' from dual;
-- 4月份最后一天
select last_day(to_date('20200401','yyyymmdd')) from dual;

--5 months_between 获得两个日期之间月数
select months_between( to_date('2020-05-31 23:59:59','yyyy-mm-dd hh24:mi:ss') , to_date('20200401','yyyymmdd') ) from dual;
-- 你今年几岁了?
-- 1) 获得出生日期距离今日月数
select months_between( sysdate , to_date('20000624','yyyymmdd') ) from dual;
-- 2) 获得出生日期距离今日年数(含小数位)
select months_between( sysdate , to_date('20000624','yyyymmdd') ) / 12 from dual;
-- 3) 向上取值 19.8 --> 20
select ceil ( months_between( sysdate , to_date('20000624','yyyymmdd') ) / 12 ) from dual;
-- 4) 拼接“岁”字符串
select ceil ( months_between( sysdate , to_date('20000624','yyyymmdd') ) / 12 ) || '岁' from dual;

-- 6 下一个指定日期 next_day(日期, 星期)
-- 星期日为一周的第一天,可以使用1表示
select next_day( sysdate , '星期日') from dual;
select next_day( sysdate , 1) from dual;  

-- 7 四舍五入日期格式化
-- yyyy 四舍五入年,返回日期,有效数据是年,不需要考虑月和日
select round( sysdate , 'yyyy') from dual;
-- mm 四舍五入月,返回日期,有效数据是月,不需要考虑日
select round( sysdate , 'mm') from dual;

-- 8 格式化
-- 一年的第一天
select trunc( sysdate , 'yyyy') from dual;
-- 这个月的第一天
select trunc( sysdate , 'mm') from dual;
-- 这个星期的第一天
select trunc( sysdate , 'day') from dual;

5.4、转换函数

---转换函数
-- 1. to_char 将日期转换字符串
-- yyyy 年
-- mm 月
-- dd 日
-- hh 时(12小时制)
-- hh24 时
-- mi 分
-- ss 秒
select to_char(1024) from dual;
select to_char( sysdate , 'yyyy-mm-dd hh:mi:ss') from dual;
select to_char( to_date('2020-05-27 20:27:42', 'yyyy-mm-dd hh24:mi:ss') , 'yyyy-mm-dd hh24:mi:ss') from dual;
-- 2. to_date 将字符串转换日期
-- 3. to_number 将数字字符串转换数字
select to_number('1024') from dual;
select to_number('1024.24') from dual;

5.5、其他函数

--- 其他函数
-- 1 nvl(字段, 如果为null显示数据 )
select nvl(t.usenum,0), t.* from t_account t

-- 2 nvl2(字段, 不为null显示,为null显示)
select nvl2(t.usenum,100, 0), t.* from t_account t;

-- nvl2(t.usenum,t.usenum, 0) 等效 nvl(t.usenum,0) 
select nvl2(t.usenum,t.usenum, 0), t.* from t_account t

-- 3 decode 相当于 java switch
select decode(id,1,'哈哈',2,'嘿嘿',3,'嘿嘿嘿') from t_area;
--select decode(sex,1,'男',0,'女') from t_user;

6、分析函数

-- 分析函数--排名
insert into book(bid,title) values(1,'100');
insert into book(bid,title) values(2,'98');
insert into book(bid,title) values(3,'98');
insert into book(bid,title) values(4,'95');
insert into book(bid,title) values(5,'98');
insert into book(bid,title) values(6,'95');
commit;

-- 1 查询所有数据
select * from book;

-- 2 排名跳跃
select rank() over( order by b.title desc ) , b.* from book b;
-- 3 排名连续
select dense_rank() over( order by b.title desc ) , b.* from book b;
-- 4 连续的排序
select row_number() over( order by b.title desc ) , b.* from book b;
  • rank() 排名跳跃

  • dense_rank() 排名连续

  • row_number() 连续的排序

7、集合运算

  • 集合运算:将两个结果集合并成一个结果集
--语法
select 语句
集合运算关键
另一条select 语句;

--集合运算关键字
union all , 并集,不去重
union,并集,去重
intersect 并集,获得公共部分
minus 差集,第一条减去公共部分
-- 集合运算
-- 0 准备工作
-- 0.1 查询id 小于等于 7 
select * from t_owners where id <= 7;
-- 0.2 查询 id 大于等于 5
select * from t_owners where id >= 5;

-- 1 并集,允许重复
select * from t_owners where id <= 7
union all
select * from t_owners where id >= 5;

-- 2 并集,去重
select * from t_owners where id <= 7
union
select * from t_owners where id >= 5;

-- 3 交集,共同部分
select * from t_owners where id <= 7
intersect
select * from t_owners where id >= 5;

-- 4 差集,减去公共部分
select * from t_owners where id <= 7
minus
select * from t_owners where id >= 5;

7.1、综合案例

-- 2. 统计某收费员某日的收费,按区域分组汇总
-- 1) 查找某收费员某日的收费
select ac.* from t_account ac
where ac.feeuserid = 2 and to_char(ac.feedate , 'yyyy-mm-dd') = '2012-05-14'
-- 2) 按区域分组:区域id、用水量、金额
select ac.areaid, sum(ac.usenum) / 1000 , sum(ac.money) from t_account ac
where ac.feeuserid = 2 and to_char(ac.feedate , 'yyyy-mm-dd') = '2012-05-14'
group by ac.areaid
-- 3) 显示区域名称
select (select name from t_area where id = ac.areaid), sum(ac.usenum) / 1000 , sum(ac.money) from t_account ac
where ac.feeuserid = 2 and to_char(ac.feedate , 'yyyy-mm-dd') = '2012-05-14'
group by ac.areaid


-- 3. 统计某年某月的收费记录,按区域分组汇总
select (select name from t_area where id = ac.areaid ) 区域, sum(ac.usenum) / 1000 "用水量(吨)", sum(ac.money) 金额 from t_account ac
where to_char( ac.feedate, 'yyyy-mm' ) = '2012-05'
group by ac.areaid


-- 4. 统计某收费员某年某月的收费记录,按区域分组汇总
select (select name from t_area where id = ac.areaid), sum(ac.usenum) / 1000 , sum(ac.money) from t_account ac
where ac.feeuserid = 2 and to_char(ac.feedate , 'yyyy-mm') = '2012-05'
group by ac.areaid


-- 5. 统计某年收费情况,按区域分组汇总
select (select name from t_area where id = ac.areaid ) 区域, sum(ac.usenum) / 1000 "用水量(吨)", sum(ac.money) 金额 from t_account ac
where to_char( ac.feedate, 'yyyy' ) = '2012'
group by ac.areaid

-- 6. 统计某年收费情况,按月份分组汇总
-- 1) 显示 每个月吨数、金额
select to_char( ac.feedate ,'mm' ),  ac.* from t_account ac
where to_char( ac.feedate ,'yyyy' ) = '2013'
-- 2) 按照月进行分组、聚合
select to_char( ac.feedate ,'mm' ),  sum(ac.usenum) / 1000, sum(ac.money) from t_account ac
where to_char( ac.feedate ,'yyyy' ) = '2013'
group by to_char( ac.feedate ,'mm' )
order by to_char( ac.feedate ,'mm' )


-- 7. 根据业主类型分别统计每种居民的用水量(整数,四舍五入)及收费金额 ,如果该类型在台账表中无数据也需要列出值为0的记录 
-- 1) 查询业主类型 + 对应台账信息
select ow.name , ac.usenum, ac.money 
from t_ownertype ow
left outer join t_account ac on ow.id = ac.ownertypeid
-- 2) 按照业主名称分组,使用量和金额求和
select ow.name , nvl( round(sum(ac.usenum) / 1000) , 0 ) "用水量(吨)", nvl ( sum(ac.money ),0 ) 金额
from t_ownertype ow
left outer join t_account ac on ow.id = ac.ownertypeid
group by ow.name 


-- 8. 统计每个区域的业主户数,并列出合计
-- 1) 显示区域,以及业主信息
select ar.name , ow.* from t_area ar
inner join t_address ad on ar.id = ad.areaid
inner join t_owners ow on ad.id = ow.addressid
-- 2) 进行业主户数统计
select ar.name , count(ow.id) from t_area ar
inner join t_address ad on ar.id = ad.areaid
inner join t_owners ow on ad.id = ow.addressid
group by ar.name 
-- 3)并列出合计
select ar.name , count(ow.id) from t_area ar
inner join t_address ad on ar.id = ad.areaid
inner join t_owners ow on ad.id = ow.addressid
group by ar.name 
union 
select '合计', count(1) from t_owners ow;


-- 9 统计每个区域的业主户数,如果该区域没有业主户数也要列出0 
-- 1) 显示区域,以及业主信息,如果没有业主,显示null
select ar.name,ow.* from t_area ar
left outer join t_address ad on ar.id = ad.areaid
left outer join t_owners ow on ad.id = ow.addressid
-- 2) 分组+计数
select ar.name,count(ow.id) from t_area ar
left outer join t_address ad on ar.id = ad.areaid
left outer join t_owners ow on ad.id = ow.addressid
group by ar.name
-- 3) 优化
select ar.name 区域,count(ow.id) 业主户数 from t_area ar
left outer join t_address ad on ar.id = ad.areaid
left outer join t_owners ow on ad.id = ow.addressid
group by ar.name

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值