帮助SQL查询,这可能吗?

我正在开发一个系统来处理会员循环计费。 要购买的物品可以组合在一起以获得特殊的包装价格,或者单独购买以获得更高的独立费率。 我的数据库模式中决定重复项目支付金额的部分由以下4个表格组成:

MEMBER_RECUR_GROUP
member_id(PK)
recur_group_id(PK)

RECUR_GROUP
recur_group_id(PK)

RECUR_GROUP_ITEM
recur_group_id(PK)
recur_item_id(PK)
recur_amount

RECUR_ITEM
recur_item_id(PK)
项目代码
recur_term

基本上,项目被附加到重复组,然后与成员关联。 同一项目可以出现在给定成员的多个重复组中。

例如,假设我们有3个简单的项目:苹果,橙子和香蕉。 可以有一个包含所有3的重复组(在这个组中的单个项目价格将是最便宜的,例如每个1美元)。 也可以有一个重复组合,只有2个项目,比如橙色和香蕉。 对于苹果公司来说,可以有一个重复的组合(这是独立的价格,比如2美元,比其他组合中的“打包”价格高),另一个是橙色,另一个是香蕉。

给定一个member_id和一个或多个item_codes(可能是CSV,类似“apple,banana”),我希望查询从包含所有item_codes的recur_group中为每个item_code返回recur_term和recur_amount。 如果没有包含所有项目的recur_group,则应返回单个项目的独立recur_group的recur_term和recur_amount值。 这可能在单个查询中实现吗?

如果实现很重要,我正在使用SQL Server 2005。 谢谢!

以下是示例数据,其中预期结果如下。

MEMBER_RECUR_GROUP
1,1

1,3
1,4
1,5

RECUR_GROUP
1
2
3
4

RECUR_GROUP_ITEM
1,1,1.00
1,2,1.00
1,3,1.00

2,2,1.50
2,3,1.50

3,1,2.00
4,2,2.00
5,3,2.00

RECUR_ITEM
1,苹果,3
2,橙色,3
3,香蕉3

如果成员标识1为苹果,橙子和香蕉自动计费,则使用重复组标识1的价格。
如果成员标识1为Apple和Orange自动计费,则使用重复组标识为3和4的组合定价。 (因为会员ID 1没有苹果和橙色的重复组。)
如果成员标识1为橙色和香蕉自动计费,则使用重复组标识2的定价。
如果会员ID为Apple自动计费,则使用重复组ID 3的定价。
如果成员标识1为橙色自动计费,则使用重复组标识4的定价。
如果成员标识1为香蕉自动计费,则使用重复组标识为5的定价。


这可能会让你朝着正确的方向前进。 首先,最大的问题是,即使是中等数量的项目和/或组,这种计算也会失控。

我在这里写的查询是为MySQL编写的,我确信其中的一些内容在SQL Server中不可用,但我可以修改它。 我不得不跳过特定于MySQL的许多箍环来获得每个组合项目的最便宜行。 据我所知,MS SQL实际上更容易,因为它似乎支持FIRST聚合函数。

此外,您没有具体说明您的情况是否有意义让某人获得同一项目的倍数。 我假设没有,但如果你删除了条款,它将包括倍数。

中心问题是您需要生成所有可能的组合,这些组合可能包括所有购买的元素。 要做到这一点,必须将recur_group表加入自己,直到购买的物品数量。 在我的示例查询中,我最多包含4个自连接,它将覆盖最多4个项目的所有可能组合。

如果组和价格不会经常更改,则可以将查询结果存储到一个表中,该表在每次数据更改时都会重新填充。

但是底线是,除非你只有很少的组和项目,否则你可能需要简化一些东西。

set @type = '';
set @num  = 1;

select item_list, total, g1, g2, g3, g4,
       @num := if(@type = item_list, @num + 1, 1) as row_number,
       @type := item_list as dummy
from (
    select group_concat(i.item_code order by i.item_code separator ',')
           as item_list, 
           ( select sum(recur_amount) 
             from recur_group_item 
             where recur_group_id in (
                 perms.g1, perms.g2, perms.g3, perms.g4
             )) as total,
           perms.g1, perms.g2, perms.g3, perms.g4
    from recur_item i
    join recur_group_item gi
    on gi.recur_item_id = i.recur_item_id
    join (
        select recur_group_id as g1, 
               null as g2, null as g3, null as g4
        from recur_group
        union 
        select g1.recur_group_id as g1, g2.recur_group_id as g2, 
               null as g3, null as g4
        from recur_group g1, recur_group g2
        where g1.recur_group_id < g2.recur_group_id
        union
        select g1.recur_group_id as g1, g2.recur_group_id as g2, 
               g3.recur_group_id as g3, null as g4
        from recur_group g1, recur_group g2, recur_group g3
        where g1.recur_group_id < g2.recur_group_id
        and g2.recur_group_id < g3.recur_group_id
        union
        select g1.recur_group_id as g1, g2.recur_group_id as g2, 
               g3.recur_group_id as g3, g4.recur_group_id as g4
        from recur_group g1, recur_group g2, recur_group g3, recur_group g4
        where g1.recur_group_id < g2.recur_group_id
        and g2.recur_group_id < g3.recur_group_id
        and g3.recur_group_id < g4.recur_group_id
    ) as perms
    on gi.recur_group_id in (perms.g1, perms.g2, perms.g3, perms.g4)
    group by perms.g1, perms.g2, perms.g3, perms.g4
    having count(i.item_code) = count(distinct i.item_code)
    order by item_list asc, total asc
) as groupings
group by item_list, total, g1, g2, g3, g4
having row_number = 1;

其中,稍微扩展的数据集产生类似于此的结果:

item_list                      total  g1  g2      g3      g4      
-----------------------------  -----  --  ------  ------  ------  
apple                          2.0    3   (null)  (null)  (null)  
apple,banana                   4.0    3   5       (null)  (null)  
apple,banana,onion             4.0    5   9       (null)  (null)  
apple,banana,onion,orange      5.0    2   9       (null)  (null)  
apple,banana,onion,pear        7.0    5   6       9       (null)  
apple,banana,onion,pineapple   8.0    5   7       9       (null)  
apple,banana,orange            3.0    1   (null)  (null)  (null)  
apple,banana,orange,pear       6.0    1   6       (null)  (null)  
apple,banana,orange,pineapple  7.0    3   5       10      (null)  
apple,banana,pear              7.0    3   5       6       (null)  
apple,banana,pear,pineapple    11.0   3   5       6       7       
apple,banana,pineapple         8.0    3   5       7       (null)  
apple,onion                    2.0    9   (null)  (null)  (null)  
apple,onion,orange             4.0    4   9       (null)  (null)  
apple,onion,orange,pear        7.0    4   6       9       (null)  
apple,onion,orange,pineapple   5.0    9   10      (null)  (null)  
apple,onion,pear               5.0    6   9       (null)  (null)  
apple,onion,pear,pineapple     9.0    6   7       9       (null)  
apple,onion,pineapple          6.0    7   9       (null)  (null)  
apple,orange                   4.0    3   4       (null)  (null)  
apple,orange,pear              7.0    3   4       6       (null)  
apple,orange,pear,pineapple    8.0    3   6       10      (null)  
apple,orange,pineapple         5.0    3   10      (null)  (null)  
apple,pear                     5.0    3   6       (null)  (null)  
apple,pear,pineapple           9.0    3   6       7       (null)  
apple,pineapple                6.0    3   7       (null)  (null)  
banana                         2.0    5   (null)  (null)  (null)  
banana,onion                   8.0    5   8       (null)  (null)  
banana,onion,orange            9.0    2   8       (null)  (null)  
banana,onion,orange,pear       12.0   2   6       8       (null)  
banana,onion,orange,pineapple  11.0   5   8       10      (null)  
banana,onion,pear              11.0   5   6       8       (null)  
banana,onion,pear,pineapple    15.0   5   6       7       8       
banana,onion,pineapple         12.0   5   7       8       (null)  
banana,orange                  3.0    2   (null)  (null)  (null)  
banana,orange,pear             6.0    2   6       (null)  (null)  
banana,orange,pear,pineapple   8.0    5   6       10      (null)  
banana,orange,pineapple        5.0    5   10      (null)  (null)  
banana,pear                    5.0    5   6       (null)  (null)  
banana,pear,pineapple          9.0    5   6       7       (null)  
banana,pineapple               6.0    5   7       (null)  (null)  
onion                          6.0    8   (null)  (null)  (null)  
onion,orange                   8.0    4   8       (null)  (null)  
onion,orange,pear              11.0   4   6       8       (null)  
onion,orange,pear,pineapple    12.0   6   8       10      (null)  
onion,orange,pineapple         9.0    8   10      (null)  (null)  
onion,pear                     9.0    6   8       (null)  (null)  
onion,pear,pineapple           13.0   6   7       8       (null)  
onion,pineapple                10.0   7   8       (null)  (null)  
orange                         2.0    4   (null)  (null)  (null)  
orange,pear                    5.0    4   6       (null)  (null)  
orange,pear,pineapple          6.0    6   10      (null)  (null)  
orange,pineapple               3.0    10  (null)  (null)  (null)  
pear                           3.0    6   (null)  (null)  (null)  
pear,pineapple                 7.0    6   7       (null)  (null)  
pineapple                      4.0    7   (null)  (null)  (null)  
链接地址: http://www.djcxy.com/p/62059.html

上一篇: Help with SQL Query, is this possible?

下一篇: Finding the difference in rows in query using SQLite