使用 Oracle 中列的值执行子查询

Performing a subquery using values from a column in Oracle

我正在尝试在 SQL 中创建计算列。基本上我需要获得一组不同的日期并确定在该特定日期人口中有多少客户。结果应该是这样的:

Date______| Customers

2016-01-01 | 1

2016-01-01 | 2

2016-01-05 | 3

2016-02-09 | 4

etc.

我使用以下脚本创建了一个示例数据库和数据(使用 MySQL,因为我没有在我们的 Oracle 数据库中创建表的权限):

create database customer_example;
use customer_example;

create table customers (
customer_id int not null primary key,
customer_name varchar(255) not null,
term_date DATE);

create table employee (
employee_id int not null primary key,
employee_name varchar(255) not null);

create table cust_emp (
ce_id int not null AUTO_INCREMENT,
emp_id int not null,
cust_id int not null,
start_date date,
end_date date,
deleted_yn boolean,
primary key (emp_id, cust_id, ce_id),
foreign key (cust_id) references customers(customer_id),
foreign key (emp_id) references employee(employee_id));


insert into customers (customer_id, customer_name)
values (1, 'Bobby Tables'), (2, 'Grover Cleveland'), (3, 'Chester Arthur'), (4, 'Jan Bush'), (5, 'Emanuel Porter'), (6, 'Darren King'), (7, 'Casey Mcguire'), (8, 'Robin Simpson'), (9, 'Robin Tables'), (10, 'Mitchell Arnold');

insert into customers (customer_id, customer_name, term_date)
values (11, 'Terrell Graves', '2017-01-01'), (12, 'Richard Wagner', '2016-10-31'), (13, 'Glenn Saunders', '2016-11-19'), (14, 'Bruce Irvin', '2016-03-11'), (15, 'Glenn Perry','2016-06-06'), (16, 'Hazel Freeman', '2016-07-10'), 
(17, 'Martin Freeman', '2016-02-11'), (18, 'Morgan Freeman', '2017-02-01'), (19, 'Dirk Drake', '2017-01-12'), (20, 'Fraud Fraud', '2016-12-31');

insert into employee (employee_id, employee_name)
values (1000, 'Cedrick French'), (1001, 'Jane Phillips'), (1002, 'Brian Green'), (1003, 'Shawn Brooks'), (1004, 'Clarence Thomas');

insert into cust_emp (emp_id, cust_id, start_date, end_date)
values (1000, 1, '2016-01-01', '2016-02-01'), (1000, 1, '2016-02-01', '2016-02-01'), (1000, 2,'2016-01-05', '2016-01-16'),(1000, 3,'2016-02-09', '2016-03-14'),(1000, 4,'2016-03-20', '2016-04-23'),
(1000, 5,'2016-01-01', '2016-01-16'),(1000, 6,'2016-01-01', '2016-01-16'),(1004, 7, '2016-01-14', '206-01-16'),
(1004, 8, '2016-01-13', '2016-01-16'),(1004, 9, '2016-01-05', '2016-01-16'), (1003, 12, '2016-04-21', '2016-11-30');

insert into cust_emp (emp_id, cust_id, start_date, deleted_yn)
values (1002, 11, '2016-04-10', TRUE),(1003, 10, '2016-01-16', FALSE), (1004, 12, '2016-04-20', TRUE), (1004, 12, '2016-04-19', FALSE), (1003, 13, '2016-06-06', TRUE), (1002, 14, '2016-06-10', TRUE),
(1004, 15, '2016-03-25', TRUE), (1004, 17, '2016-01-02', TRUE), (1004, 18, '2017-01-01', TRUE), (1004, 19, '2016-11-13', TRUE), (1004, 20, '2016-03-10', TRUE), (1004, 16, '2016-05-13', TRUE);


insert into cust_emp (emp_id, cust_id, start_date)
values (1002, 1, '2016-02-01'), (1004, 2, '2016-01-16'),(1003, 3, '2016-03-14'),(1002, 4, '2016-04-23'),(1004, 5, '2016-01-16'),(1002, 6, '2016-01-16'),(1004, 7, '2016-01-16'),
(1004, 8, '2016-01-16'),(1002, 9, '2016-01-16'), (1004, 10, '2016-01-16');

下面的 SQL 在 MySQL 中工作正常,但是当我在 Oracle 中尝试它时,我在 'dates' 上得到一个 'invalid identifier':

select distinct(ce.start_date) as dates,
(select count(distinct(c.customer_id)) 
from customers c
    inner join cust_emp ce on c.customer_id = ce.cust_id
where ce.start_date < dates
    and (ce.end_date > dates or (ce.deleted_yn = false or ce.deleted_yn is null))
    and (c.term_date > dates or c.term_date is null)
)
from cust_emp as ce;

这似乎是因为子查询中的日期太远了。我也尝试过 CTE,但这似乎有同样的问题,因为它给出了同样的错误。我怎样才能重写这个,以便我可以评估 Oracle 中每个日期有多少客户?

嗯?

这不就是你想要的吗?

select ce.dates as dates, count(distinct c.customer_id) 
from cust_emp ce join
     customers c
     on c.customer_id = ce.cust_id
where ce.start_date < ce.dates and
      (ce.end_date > ce.dates or ce.deleted_yn = false or ce.deleted_yn is null) and
      (c.term_date > ce.dates or c.term_date is null)
group by ce.dates
order by ce.dates;

我不太明白select distinct的子查询的用法。你描述的逻辑更容易理解为一个简单的聚合。

我不确定 dates 来自哪里。它不在您的数据模型中,但在您的示例查询中。