我有3个表:客户,属性和住宿。表客户包含有关客户(customer_id, name, surname, email...
)的所有数据。表格属性包含所有属性(property_id, property_name...
的列表,表格停留包含客户的所有较早停留(customer_id, property_id, stay_id, arrival_date, departure_date...
)。
一些顾客多次入住多个酒店,而有些顾客则是第一次来。 有人可以解释一下oracle sql查询,该查询仅返回第一次在任何属性中进行样式设置的客户。
对不起,您回答晚了。 这就是我到目前为止所得到的。
表格: 客户$ A $
住宿$ B $
物业$ C $
Customer_Fragments $ D $
SELECT a.RIID_,
sub.CUSTOMER_ID_,
sub.PROPERTY_ID,
b.ARRIVAL_DATE,
c.PROPERTY_SEGMENT,
ROW_NUMBER() OVER (
PARTITION BY sub.CUSTOMER_ID_,
sub.PROPERTY_ID
ORDER BY
sub.CUSTOMER_ID_ asc
) RN
FROM
(
SELECT
b.CUSTOMER_ID_,
b.PROPERTY_ID
FROM
$B$ b
GROUP BY
b.CUSTOMER_ID_,
b.PROPERTY_ID
HAVING
COUNT(*)= 1
) sub
INNER JOIN $A$ a ON sub.CUSTOMER_ID_ = a.CUSTOMER_ID_
INNER JOIN $B$ b ON sub.CUSTOMER_ID_ = b.CUSTOMER_ID_
INNER JOIN $C$ c ON sub.PROPERTY_ID = c.PROPERTY_ID
LEFT JOIN $D$ d ON a.RIID_ = d.RIID_
WHERE
b.ARRIVAL_DATE = TRUNC(SYSDATE + 7)
AND c.PROPERTY_DESTINATION = 'Destination1'
AND lower(c.NAME_) NOT LIKE ('unknown%')
AND a.NWL_PERMISSION_STATUS = 'I'
AND a.EMAIL_DOMAIN_ NOT IN ('abuse.com', 'guest.booking.com')
AND (d.BLACKLISTED != 'Y'
or d.BLACKLISTED is null
)
我想选择所有从今天起7天到达Destination1的客户,以告知他们一些活动。客户可以预订几个 目的地1中的属性并具有相同的到达日期(例如:我可以为我和我的妻子在属性1中预订房间,也可以为我的朋友预订属性2中的房间。我们都在同一到达日期到达目的地1)。 在这种情况下,我只想向客户发送一封信息电子邮件,而不是两封电子邮件。在这种情况下,上述SQL查询返回两行,我希望它仅返回一行(一行=一封电子邮件)。
答案 0 :(得分:0)
WITH first_stays (customer_id, property_id, first_time_arrival_date, stay_no) AS
(
SELECT s.customer_id
, s.property_id
, s.arrival_date AS first_time_arrival_date
, ROW_NUMBER() OVER (PARTITION BY s.customer_id, s.property_id ORDER BY s.arrival_date) stay_no
FROM stays s
)
SELECT c.surname AS customer_surname
, c.name AS customer_name
, p.property_name
, s.first_time_arrival_date
FROM customer c
INNER
JOIN first_stays s
ON s.customer_id = c.customer_id
AND s.stay_no = 1
INNER
JOIN property p
ON p.property_id = s.property_id
第一部分WITH first_stays
是CTE(公用表表达式,在Oracle中称为subquery factoring),它将使用窗口函数对到达日期排序的每对(customer_id, property_id)
的停留次数进行编号ROW_NUMBER()。然后,只需将这些值连接到客户和属性表即可获取其名称或其他名称,然后应用stay_no = 1
(首次入住)条件。
答案 1 :(得分:0)
总是需要发布您已经尝试编写的代码,以便我们比最终错误更能帮助您。
话虽如此,我将尽力帮助您编写完整的代码。 试试这个:
select cus.*
from customers cus
join stays st
on st.customer_id = cus.customer_id
where st.arrival_date >= YOUR_DATE --for example SYSDATE or TRUNC(SYSDATE)
and 1 = (select count(*)
from stays st2
where st2.customer_id = cus.customer_id)
您尚未指定它,但是我猜测您有兴趣让初次到达日期在某个指定日期或之后的首次客户。我已将其写到WHERE clause
的代码中,您应该在其中输入这样的日期。
如果您删除WHERE clause
的那一部分,您将获得所有只住过一次的客户(例如,即使那个唯一住过的客户是10年前)。而且,如果您删除了代码的那部分,那么您也可以从查询中删除join on stays st
表,因为该联接的唯一原因是需要访问到达日期。
如果您还需要解释代码的其他部分,请在注释中询问此答案。
希望我能帮上忙!
答案 2 :(得分:0)
如果我正确理解了这个问题,那么这不是一个复杂的查询:
select c.*
from c join
(select s.customer_id
from stays s
group by s.customer_id
having count(*) = 1
) s
on s.customer_id = c.customer_id;