现在有M个市场,每个市场有不同的经营类型(例如:卖电器的和卖食品的A市场,卖食品和儿童用品的B市场,
卖纺织品和儿童用品的和日常用品的C市场,五金的D市场,等等)每个市场的经营类型有一种或多种不定,
还有L个商户,也知道每个商户的经营类型,现在需要把这L个商户依据经营类型安排到这M个市场中,
卖电器的和卖食品安排到卖电器的和卖食品的A市场,卖纺织品和儿童用品的商户安排到卖纺织品和儿童用品的B市场...,
并当一个商户在某一个市场中已经经营了某一个类型的商品后则不可以在其他包含此经营类型的不同市场经营同一类型的商品
怎么样在市场中安排最多数量的商户。例如:
商户:狗三,他的经营类型有儿童用品、日常用品、卖食品市场:
卖电器的和卖食品的A市场
卖食品和儿童用品的B市场
卖纺织品和儿童用品的和日常用品的C市场
五金的D市场合理的安排:
给狗三安排:
1、A市场卖食品摊位
2、B市场卖儿童用品
3、C市场卖日常用品
这样可以给狗三在3个市场中安排3个
不合理的安排:
给狗三安排:
1、B市场卖卖食品
2、C市场卖儿童用品(或日常用品)由于商户的安排是随机抽取,故怎样能在市场中安排最多数量的商户。并不能用游标和动态SQL语句

解决方案 »

  1.   

    --建立环境
    --市场数据
    declare @市场 table (
    市场 nvarchar(20),
    类型 nvarchar(20)
    )insert @市场
    select N'A市场',N'电器'
    union all
    select N'A市场',N'食品'
    union all
    select N'B市场',N'食品'
    union all
    select N'B市场',N'儿童用品'
    union all
    select N'C市场',N'纺织品'
    union all
    select N'C市场',N'儿童用品'
    union all
    select N'C市场',N'日常用品'
    union all
    select N'D市场',N'五金'--商户数据
    declare @商户 table (
    商户  nvarchar(20),
    类型 nvarchar(20)
    )
    insert @商户
    select N'狗三',N'食品'
    union all
    select N'狗三',N'儿童用品'
    union all
    select N'狗三',N'日常用品'
    union all
    select N'猫4',N'五金'
    union all
    select N'猫4',N'电器'
    union all
    select N'猫4',N'儿童用品'
    union all                        --找个全做的
    select N'猪5',N'纺织品'
    union all
    select N'猪5',N'电器'
    union all
    select N'猪5',N'食品'
    union all
    select N'猪5',N'儿童用品'
    union all
    select N'猪5',N'五金'
    union all
    select N'猪5',N'日常用品'
    --开始计算
    --存放结果和临时数据
    declare @结果 table (
    id int IDENTITY(1,1),
    市场 nvarchar(20),
    商户  nvarchar(20),
    类型 nvarchar(20),
    选中 int
    )--产生所有可能结果备选
    insert @结果 (市场,商户,类型,选中)
    select a.市场,b.商户,a.类型,0 as 选中 from @市场 a, @商户 b
    where a.类型=b.类型while exists ( select 1 from @结果 where 选中=0)
    beginupdate a 
    set 选中=1
    from @结果 a
    where 选中=0
    and not exists (
    select 1 from @结果
    where 商户=a.商户 and 市场=a.市场 and 选中 in (0,1)
    and id<>a.id
    )
    and not exists (
    select 1 from @结果 b
    where id<>a.id
    and 类型=a.类型
    and 商户=a.商户
    and 选中 in (0,1)
    and not exists (
    select 1 from @结果
    where 商户=b.商户 and 市场=b.市场 and 选中 in (0,1)
    and id<>b.id
    )
    )update a
    set 选中=2
    from @结果 a,@结果 b
    where a.选中=0 and b.选中=1
    and a.商户=b.商户 and a.类型=b.类型
    update a 
    set 选中=1
    from @结果 a
    where 选中=0
    and not exists (
    select 1 from @结果
    where 商户=a.商户 and 类型=a.类型 and 选中 in (0,1)
    and id<>a.id
    )
    and not exists (
    select 1 from @结果 b
    where id<>a.id
    and 商户=a.商户
    and 市场=a.市场
    and 选中 in (0,1)
    and not exists (
    select 1 from @结果
    where 商户=b.商户 and 类型=b.类型 and 选中 in (0,1)
    and id<>b.id
    )
    )update a
    set 选中=2
    from @结果 a,@结果 b
    where a.选中=0 and b.选中=1
    and a.商户=b.商户 and a.市场=b.市场update a
    set 选中=1
    from @结果 a
    where 选中=0
    and not exists (
    select 1 from @结果
    where 选中=0
    and 商户=a.商户 and id<>a.id
    )
    update a
    set 选中=1
    from @结果 a
    where 选中=0 
    and not exists (
    select 1 from @结果
    where 选中=0 and 商户=a.商户 and id<>a.id and 市场<>a.市场
    )
    and not exists (
    select 1 from @结果
    where 选中=0 and 商户=a.商户 and id<a.id
    )update a
    set 选中=2
    from @结果 a,@结果 b
    where a.选中=0 and b.选中=1
    and a.商户=b.商户 and a.市场=b.市场
    update a
    set 选中=1
    from @结果 a
    where 选中=0 
    and not exists (
    select 1 from @结果
    where 选中=0 and 商户=a.商户 and id<>a.id and 类型<>a.类型
    )
    and not exists (
    select 1 from @结果
    where 选中=0 and 商户=a.商户 and id<a.id
    )update a
    set 选中=2
    from @结果 a,@结果 b
    where a.选中=0 and b.选中=1
    and a.商户=b.商户 and a.类型=b.类型
    end--显示结果
    select * from @结果
    where 选中=1
    order by 商户
      

  2.   

    --结果
    id          市场                   商户                   类型                   选中          
    ----------- -------------------- -------------------- -------------------- ----------- 
    3           A市场                  狗三                   食品                   1
    7           B市场                  狗三                   儿童用品                 1
    14          C市场                  狗三                   日常用品                 1
    6           B市场                  猪5                   食品                   1
    2           A市场                  猪5                   电器                   1
    10          C市场                  猪5                   纺织品                  1
    17          D市场                  猪5                   五金                   1
    1           A市场                  猫4                   电器                   1
    16          D市场                  猫4                   五金                   1
    8           B市场                  猫4                   儿童用品                 1(所影响的行数为 10 行)
      

  3.   

    多谢Yang_(扬帆破浪) 的回答。
    目前能理解40%左右,但是有一个问题,我是在一个Proc中获取数据(获取的数据量大概10w-30w不定,从这些数据中通过比较复杂的业务规则,大概会筛选出50%的数据,现耗时5分钟),所以我要考虑效率。我都是采取批操作的方式。如果采用while exists ( select 1 from @结果 where 选中=0)那么在这样的数据量下是否可以?是否有不用逐条计算的可能?
    昨天我也想了很多不知道是否正确先说一下了,我的想法是在获取这10w-30w的数据以前,将这些商户的经营类型就分配的市场的重复数量来排一个优先级。
    --------------------------------------------------------------------------
    如我上面的例子:
    商户:狗三,他的经营类型有儿童用品、日常用品、卖食品市场:
    卖电器的和卖食品的A市场
    卖食品和儿童用品的B市场
    卖纺织品和儿童用品的和日常用品的C市场
    五金的D市场就狗三而言“儿童用品”在A-D个市场中出现2次,“日常用品”在A-D个市场中出现1次,“卖食品”在A-D个市场中出现2次,那么“日常用品”的优先级就最高,而当C市场已经被占用,只有A和B市场的时候那么其次是“儿童用品”,最后是“卖食品”。有感觉Yang_(扬帆破浪)好像也是有这个思路的。不知道我说的对不对。
      

  4.   

    比较有意思,个人测试如下,楼主可以参考一下,方法是很简单的:--经营类型表
    CREATE TABLE 经营类型(经营类型ID int IDENTITY(1,1),单位名称 nvarchar(20))
    --市场表
    CREATE TABLE 市场(市场ID int IDENTITY(1,1),市场名称 nvarchar(20))
    --商户表
    CREATE TABLE 商户(商户ID int IDENTITY(1,1),商户名称 nvarchar(20))
    --商户经营类型表
    CREATE TABLE 商户经营类型(商户ID int,经营类型ID int)
    --各个市场摊位分布表
    CREATE TABLE 市场摊位分布(分布ID int IDENTITY(1,1), 市场ID int ,经营类型ID int,商户ID int)--插入测试数据
    INSERT INTO 经营类型
    SELECT (N'卖食品') UNION ALL
    SELECT (N'儿童用品') UNION ALL
    SELECT (N'日常用品') UNION ALL
    SELECT (N'纺织品') UNION ALL
    SELECT (N'五金产品') 
    INSERT INTO 市场
    SELECT (N'A') UNION ALL
    SELECT (N'B') UNION ALL
    SELECT (N'C') UNION ALL
    SELECT (N'D')
    INSERT INTO 商户
    SELECT (N'商户1') UNION ALL
      SELECT (N'商户2') UNION ALL
    SELECT (N'商户3') 
    INSERT INTO 商户经营类型
    SELECT 1,2 UNION ALL
    SELECT 1,1 UNION ALL
    SELECT 1,3 UNION ALL
    SELECT 2,2 UNION ALL
    SELECT 2,3 UNION ALL
    SELECT 2,1 UNION ALL
    SELECT 3,4 UNION ALL
    SELECT 3,2 
    INSERT INTO 市场摊位分布 (市场ID,经营类型ID)
    SELECT 1,2 UNION ALL
    SELECT 1,3 UNION ALL
    SELECT 1,4 UNION ALL
    SELECT 1,1 UNION ALL
    SELECT 2,2 UNION ALL
    SELECT 2,3 UNION ALL
    SELECT 3,1 UNION ALL
    SELECT 3,2 UNION ALL
    SELECT 3,4 
    --测试Update过程
    WHILE EXISTS(SELECT 1 FROM 市场摊位分布 WHERE 商户ID IS NULL)
    BEGIN
    UPDATE A SET A.商户ID=
    --(SELECT ...)随机找出与本市场经营类型相同的商户ID
    (SELECT TOP 1 商户ID FROM 商户经营类型 AS B1 
    WHERE NOT EXISTS(SELECT 1 FROM 市场摊位分布 AS B2 WHERE B2.经营类型ID=A.经营类型ID AND B2.商户ID=B1.商户ID)
    ORDER BY NEWID()
    )
    FROM 市场摊位分布 AS A WHERE  A.商户ID IS NULL
    AND NOT EXISTS(SELECT 1 FROM 市场摊位分布 AS B WHERE B.商户ID IS NULL AND B.分布ID<A.分布ID )
    END
    --显示结果
    SELECT * FROM 市场摊位分布 AS A 
    INNER JOIN 商户 AS B ON B.商户ID=A.商户ID
    INNER JOIN 经营类型 AS C ON C.经营类型ID=A.经营类型ID
    INNER JOIN 市场 AS D ON D.市场ID=A.市场IDORDER BY A.市场ID--删除测试表
    DROP TABLE 经营类型
    DROP TABLE 市场
    DROP TABLE 市场摊位分布
    DROP TABLE 商户
    DROP TABLE 商户经营类型