如何从oracle中的多个表中获取值,包括日期
Posted
技术标签:
【中文标题】如何从oracle中的多个表中获取值,包括日期【英文标题】:how to get value from multiple table in oracle including date 【发布时间】:2018-01-19 10:38:22 【问题描述】:我有三个表customers、orders和orderitems
客户表
CUSTOMER# LASTNAME FIRSTNAME
1001 MORALES BONITA
1002 THOMPSON RYAN
1003 SMITH LEILA
1004 PIERSON THOMAS
1005 GIRARD CINDY
1006 CRUZ MESHIA
1007 GIANA TAMMY
订单表
ORDER# CUSTOMER# ORDERDATE
1000 1005 31/MAR/09
1001 1010 31/MAR/09
1002 1011 31/MAR/09
1003 1001 01/APR/09
1004 1020 01/APR/09
订单项表
ORDER# ITEM# ISBN QUANTITY
1000 1 3437212490 1
1001 1 9247381001 1
1001 2 2491748320 1
1002 1 8843172113 2
1003 1 8843172113 1
1003 2 1059831198 1
我想为所有在 3 月份下过至少一个订单的客户打印客户姓名和客户下的订单总数。
我尝试了以下查询。我坚持这个问题。我在为 3 月至少下过一份订单的客户添加数量时遇到问题。
select c.firstname
, c.lastname
, or.orderitems#
from customers c
, orderitems or
where customer# in
(
select customer#
from orders
where order# in
(
select order#
from orderitems
where /* (query truncated) */
【问题讨论】:
为什么这个查询需要 Orderitems 表? 查找项数 您说“我想为所有在 3 月份至少下过一个订单的客户打印客户姓名和客户下的订单总数。”因此,您需要客户和订单,仅此而已。您能否发布该示例数据所需的结果? 它就像:Girard cindy 在 3 月只下了一个订单,所以只需打印 1。如果其他客户下的订单超过 1 件,则必须添加所有项目 NAME ITEM 1. Girrad Cindy 1 【参考方案1】:我想为所有在 3 月份下过至少一个订单的客户打印客户姓名和客户下的订单总数。
您不需要OrderItems
表。所以你可以这样做:
select c.lastname, c.firstname, count(*)
from customers c join
orders o
on c.CUSTOMER# = o.CUSTOMER#
group by c.lastname, c.firstname
having sum(case when orderdate >= date '2009-03-01' and orderdate < date '2009-04-01'
then 1 else 0
end) > 0;
您也可以在聚合之前进行过滤,使用exists
(或in
):
select c.lastname, c.firstname, count(*)
from customers c join
orders o
on c.CUSTOMER# = o.CUSTOMER#
where exists (select 1
from orders o2
where c.CUSTOMER# = o2.CUSTOMER# and
o2.orderdate >= date '2009-03-01' and
o2.orderdate < date '2009-04-01'
)
group by c.lastname, c.firstname
虽然我喜欢having
方法,但在聚合之前进行过滤通常效果更好。
【讨论】:
虽然问题不是很清楚,但 OP 似乎需要数量的总和,而不是订单的数量,如问题中所述 @WilliamRobertson 。 . .谢谢。【参考方案2】:如果我理解得很好,您可能需要这样的东西(假设您的日期值没有时间信息):
select LASTNAME, FIRSTNAME, sum(QUANTITY)
from customers
inner join Orders using(CUSTOMER#)
inner join Orderitems using(ORDER#)
group by LASTNAME, FIRSTNAME
having count(
case when ORDERDATE between date '2009-03-01'
and date '2009-03-31'
then 1
end
) > 0
在这里,我应用having
条件以仅让客户在 3 月份至少有一个订单。
例如:
SQL> with customers(CUSTOMER#, LASTNAME, FIRSTNAME) as
2 (
3 select 1001, 'MORALES' , 'BONITA' from dual union all
4 select 1002, 'THOMPSON', 'RYAN' from dual union all
5 select 1003, 'SMITH' , 'LEILA' from dual union all
6 select 1004, 'PIERSON' , 'THOMAS' from dual union all
7 select 1005, 'GIRARD' , 'CINDY' from dual union all
8 select 1006, 'CRUZ' , 'MESHIA' from dual union all
9 select 1007, 'GIANA' , 'TAMMY' from dual
10 ),
11 Orders(ORDER#, CUSTOMER#, ORDERDATE) as
12 (
13 select 1000, 1005, to_date('31/MAR/09', 'DD/MON/YY') from dual union all
14 select 1001, 1010, to_date('31/MAR/09', 'DD/MON/YY') from dual union all
15 select 1002, 1011, to_date('31/MAR/09', 'DD/MON/YY') from dual union all
16 select 1003, 1001, to_date('01/APR/09', 'DD/MON/YY') from dual union all
17 select 1004, 1020, to_date('01/APR/09', 'DD/MON/YY') from dual
18 ),
19 Orderitems(ORDER#, ITEM#, ISBN, QUANTITY) as
20 (
21 select 1000, 1, 3437212490, 1 from dual union all
22 select 1001, 1, 9247381001, 1 from dual union all
23 select 1001, 2, 2491748320, 1 from dual union all
24 select 1002, 1, 8843172113, 2 from dual union all
25 select 1003, 1, 8843172113, 1 from dual union all
26 select 1003, 2, 1059831198, 1 from dual
27 )
28 select LASTNAME, FIRSTNAME, sum(QUANTITY)
29 from customers
30 inner join Orders using(CUSTOMER#)
31 inner join Orderitems using(ORDER#)
32 group by LASTNAME, FIRSTNAME
33 having count(case when ORDERDATE between date '2009-03-01' and date '2009-03-31' then 1 end) > 0;
LASTNAME FIRSTN SUM(QUANTITY)
-------- ------ -------------
GIRARD CINDY 1
SQL>
【讨论】:
【参考方案3】:试试这个
select c.FIRSTNAME , c.LASTNAME , count(i.quantity)
from Customer c , Orders o , Orderitems i
where c.CUSTOMER# = o.CUSTOMER#
and o.ORDER# = i.ORDER#
and o.ORDERDATE between '01-mar-2018' and '30-mar-2018'
group by c.FIRSTNAME , c.LASTNAME;
【讨论】:
不错的答案;尽管您的group by
列与您的非聚合 select
atm 不一致(即代码不太有效)。
count
将计算出现次数,而不是总和。以这种方式使用日期是危险的,可能不起作用。这将获得 3 月份的订单数量(最多 30 个......),但对于在 3 月份下订单的用户,OP 似乎需要所有订单的总数。此外,最好切换到 ANSI 连接语法。以上是关于如何从oracle中的多个表中获取值,包括日期的主要内容,如果未能解决你的问题,请参考以下文章