2012-10-11 57 views
0

我想要做的是找到所有在第一次购买前一天购买Series XSeries A小部件的客户从那个小部件。如果他们购买了多个合格的小工具Series X需要排名,我应该只收回一个记录。希望这是有道理的所以这里的数据Oracle/SQL - 多表连接逻辑 - 不知道怎么说短语

[customers] 
c_id  cp_id 
-------------- 
1  cp1 
2  cp2 
3  cp3 
4  cp4 
5  cp5 
6  cp6 
7  cp7 
8  cp8 
9  cp9 
10  cp10 

[widget_orders - c_id maps to c_id in customers] 
c_id w_sku o_date 
---------------------- 
1  w1  2012-10-10 
2  w1  2012-10-10 
2  w2  2012-10-10 
3  w1  2012-10-10 
3  w2  2012-10-10 
4  w1  2012-10-10 
4  w2  2012-10-10 
5  w1  2012-10-10 
5  w2  2012-10-10 
6  w1  2012-10-10 
6  w2  2012-10-10 
7  w2  2012-10-10 
8  w1  2012-10-10 
9  w3  2012-10-10 

[widgets - w_sku maps to w_sku in widget_orders] 
w_sku w_series 
------------------ 
w1  Series A 
w2  Series X 
w3  Series C 

[customer_data - c_id maps to c_id in customers] 
cp_id seriesA_fPurch seriesX_fPurch 
-------------------------------------- 
cp3  
cp4  2012-09-15 
cp5      2012-09-15 
cp6  2012-09-15  2012-09-15 
cp7      2012-09-15 
cp8  2012-09-15 

,这里是数据,我想取回忽略说明()

cp_id series 
-------------- 
cp1  Series A (bought series A and had NO prior purchase history) 
cp2  Series X (bought both series, but X has rank - no purchase history) 
cp3  Series X (bought both series, but X has rank - has purchase history recors albeit not for these) 
cp4  Series X (bought both series, but X has rank - already had A history anyways) 
cp5  Series A (bought both series, although X has rank they had previously bought series X) 

下面的人不显示在结果

cp6 - they had previously bought both series 
cp7 - bought a series x, but had in the past 
cp8 - bought a series a, but had in the past 
cp9 - bought a widget in neither series 
cp10 - didnt buy anything 

希望一切都有道理,有人可以帮助我在这里!

因此,要总结的逻辑,或许定义有点更清楚这里是我会怎样形容什么需要在台阶状发生

1) Find all customers who have no matching records in the customer_data table 
2) Find all customers who have a null value in either *purch column in the customer_data table 
3) Combine these results together 
4) Take the results and find the customers who made a purchase yesterday 
5) Take the results and find the customers who purchased Series A or Series X 
6) Take the results and do the following 
    6a) If the purchase was Series A and they have a value for series A purch already drop them from results 
    6b) If the purchase was Series X and they have a value for series X purch already drop them from results 
7) Take the results and remove duplicate records based on the cp_id - Series X takes presedence over Series A 

回答

2

我不知道我完全理解你的要求,但尝试:

SELECT cp_id, w_series 
FROM (
SELECT rank() over (partition BY wo."c_id" ORDER BY decode(w."w_series",'Series X',1,'Series A',2)) rank, 
     wo."c_id" c_id, 
     c."cp_id" cp_id, 
     w."w_series" w_series 
FROM widget_orders wo JOIN widgets w ON wo."w_sku"=w."w_sku" 
    JOIN customers c on c."c_id"=wo."c_id" 
LEFT OUTER JOIN customer_data cd ON c."cp_id" = cd."cp_id" 
WHERE w."w_series" IN ('Series A', 'Series X') 
    AND trunc(wo."o_date") = trunc(sysdate)-1 
    AND ((cd."seriesA_fPurch" IS NULL AND w."w_series"='Series A') 
    OR (cd."seriesX_fPurch" IS NULL AND w."w_series"='Series X')) 
) 
WHERE rank = 1 

Here是小提琴

说明:
雅ding to step-like numbers-
1)+ 2)在LEFT OUTER JOIN + cd."seriesA_fPurch" IS NULL条件+ cd."seriesX_fPurch" IS NULL条件下完成,因为它也会找到那些没有记录并且将空值放入其中的条件。
3)明显...
4)trunc(wo."o_date") = trunc(sysdate)-1条件
5)w."w_series" IN ('Series A', 'Series X')
6)(cd."seriesA_fPurch" IS NULL AND w."w_series"='Series A') OR (cd."seriesX_fPurch" IS NULL AND w."w_series"='Series X')条件
7)通过给一个等级的记录,并根据小提琴WHERE rank = 1条件

+0

它看起来像这样会起作用,但我的确有点小声嘀咕。 customers表加入到不同字段的customer_data表中。看起来你的查询没有使用客户表,但它最终需要。我现在正在更新这个问题。 – dscl

+0

@dscl,我认为你的句子应该首先'感谢努力了解我的场景,并创建表格并用数据填充它以使这个等等......'+1只有通过这个伟大的工作。 – danihp

+0

@danihp你绝对正确!谢谢A.B.Cade看我的问题,并通过它。如果你可以再看一看,我当然会很感激,如果你不能理解,并且仍然很感谢你已经付出的努力。 – dscl