【问题标题】:Display unique combination of values per ID显示每个 ID 值的唯一组合
【发布时间】:2017-09-12 21:14:30
【问题描述】:

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

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 和 3 具有相同的值集。实际上,订单 ID 在输出中并不重要,它们只是作为属于同一订单的不同记录集的指示器。

【问题讨论】:

  • 所以,如果10个订单的Product Name、Delivery Type和Priority Type完全相同,我只需要得到一次。嗯,这正是@的定义987654327@。也许你想切换到GROUP BY Product Name, Delivery Type, 并添加MAX/MIN(ORDER ID)
  • 您不需要光标。但是,您确实需要发布一些示例数据以供任何人帮助您。正如你所拥有的,看起来你只需要使用GROUP BY进行分组。
  • "如果10个订单的产品名称、发货类型和优先级类型完全相同,我只需要得到一次。" . . .其他 9 个订单呢?
  • 至 dnoeth - 您的解决方案将返回具有特定字段值的最小/最大订单 ID。我需要其他东西 - 属于同一订单 ID 的多条记录的唯一列表。
  • 致 Gordon Linoff - 我不需要订单 ID 列表,我只需要属于同一订单 ID 的一组唯一的多条记录。

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


【解决方案1】:

由于没有人建议不使用游标的纯 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-07
    • 2017-12-18
    • 1970-01-01
    • 1970-01-01
    • 2021-05-05
    相关资源
    最近更新 更多