显示每个ID

时间:2017-09-12 21:14:30

标签: sql sql-server sql-server-2008 tsql sql-server-2008-r2

我有一个返回以下结构的查询:

ORDER ID | PRODUCT_NAME | DELIVERY_TYPE | PRIORITY_TYPE 

一个订单可能有很多产品。我需要获得每个订单Product Name, Delivery Type and Priority Type的唯一组合。因此,如果10个订单具有完全相同的Product Name, Delivery Type and Priority Type,我只需要获得一次。 只是从查询中删除订单ID并获取不同的值将无济于事,因为我不知道哪些记录属于同一order id。我相信它可以通过循环游标编写为脚本,只是想知道使用单个SQL语句是否有更优雅的解决方案。

本练习的目的如下:我们重写了我们的系统,新设计不允许每个订单有多种交付类型,因此我们将多种交付类型合并为一种。为此,我们需要了解当前存在的每个订单的产品/交付/优先级的所有可能组合,以便我们可以为每个唯一组合确定正确的单个值。

以下是数据样本:

Input data

根据查询结果,我只需要获得一系列独特的PRODUCT_NAME,DELIVERY_TYPE& PRIORITY_TYPE,所以在上面的示例中,我想获得以下内容:

Output data

请注意订单ID& 2& 4不会出现在这里,因为它们具有与订单ID相同的一组值1& 1& 3相应地。实际上,订单ID在输出中并不重要,它们只是作为不同记录的指标。属于同一订单的集合。

1 个答案:

答案 0 :(得分:0)

由于没有人建议使用纯SQL解决方案,而不使用游标,我在这里使用游标发布我的答案。 #TEMP1表是包含上图中发布的输入数据的表。

DECLARE @tmp_o_id bigint
set @tmp_o_id=0
declare @tmp_str varchar(2000)
set @tmp_str=''
DECLARE @o_id bigint
declare @product_name  varchar(51)
declare @dlv_type varchar(201)
declare @pr_type varchar(201)

DECLARE @tmp_tbl TABLE (tmp_str varchar(2000))
DECLARE @tbl TABLE (o_id bigint, product_name  varchar(51), dlv_type varchar(201), pr_type varchar(201))
DECLARE @tbl2 TABLE (o_id bigint, product_name  varchar(51), dlv_type varchar(201), pr_type varchar(201))

DECLARE cursor_o CURSOR FORWARD_ONLY READ_ONLY
FOR 
    SELECT *
    from #TEMP1 
    order by 1


OPEN cursor_o

FETCH NEXT FROM cursor_o
INTO @o_id,@product_name, @dlv_type,@pr_type

WHILE @@FETCH_STATUS = 0
BEGIN
    if @tmp_o_id<>@o_id 
        begin
            if @tmp_o_id<>0
            begin           
                if not exists (select * from @tmp_tbl where tmp_str=@tmp_str) 
                    begin               
                        insert into @tbl select * from @tbl2                    
                    end                         
                delete from @tbl2
                insert into @tmp_tbl VALUES(@tmp_str)                                                       
                set @tmp_str=''
            end                 
        end
    set @tmp_str=@tmp_str+''+@product_name+''+@dlv_type+''+@pr_type
    set @tmp_o_id=@o_id
    insert into @tbl2 VALUES(@o_id, @product_name, @dlv_type,@pr_type)  
    FETCH NEXT FROM cursor_o
    INTO @o_id, @product_name, @dlv_type,@pr_type
END 
if not exists (select * from @tmp_tbl where tmp_str=@tmp_str) 
    begin   
        insert into @tbl select * from @tbl2                    
        delete from @tbl2
    end                         
CLOSE cursor_o;
DEALLOCATE cursor_o;

SELECT * from @tbl