【问题标题】:Sql Server 2008 Selecting DistinctSql Server 2008 选择不同
【发布时间】:2015-09-11 22:46:54
【问题描述】:

我无法过滤掉重复的列值。

到目前为止,这是我的结果:

ProjectNumber, WorkOrder, Shipment, Start, End, Quantity, PartName
------------------------------------------------------------------
1234 | 1234-01 | S-01 | 2015-09-01 00:00:01 | 2015-09-01 00:00:01 | 200 | Part A
1234 | 1234-02 | S-01 | 2015-09-01 00:00:01 | 2015-09-01 00:00:01 | 200 | Part B
1234 | 1234-03 | S-01 | 2015-09-01 00:00:01 | 2015-09-01 00:00:01 | 200 | Part C
2345 | 2345-01 | S-01 | 2015-09-02 00:00:01 | 2015-09-02 00:00:01 | 12  | Part A
2345 | 2345-02 | S-01 | 2015-09-02 00:00:01 | 2015-09-02 00:00:01 | 24  | Part B

我知道我需要按 ProjectNumber 和第一个 WorkOrder 的数据进行分组,如果这有意义的话。所以想要的结果是:

ProjectNumber, WorkOrder, Shipment, Start, End, Quantity, PartName
------------------------------------------------------------------
1234 | 1234-01 | S-01 | 2015-09-01 00:00:01 | 2015-09-01 00:00:01 | 200 | Part A
2345 | 2345-01 | S-01 | 2015-09-02 00:00:01 | 2015-09-02 00:00:01 | 12  | Part A

到目前为止我尝试过的,没有骰子。

SELECT
  ProjectNumber, ProductionNotes AS Shipment, PromiseDate AS "End", Notes, 
  MIN(WorkOrderNumber) AS "Work Order", Name AS "Sales Order", PromiseDate, 
  Quantity, PartName
FROM Database.dbo.daWorkOrders
WHERE StatusTypeID = 3
GROUP BY ProjectNumber
ORDER BY PromiseDate ASC;

回复:

列“Database.dbo.daWorkOrders.ProductionNotes”在 选择列表,因为它不包含在任一聚合中 函数或 GROUP BY 子句。

可以这样做吗?

【问题讨论】:

    标签: sql-server-2008


    【解决方案1】:

    基本上,这个错误的意思是,如果你要使用 GROUP BY 子句,那么你的结果将是一个关系/表,每个组都有一行,所以在你的 SELECT 语句中你只能“选择”您作为分组依据的列并在该列上使用聚合函数,因为其他列不会出现在结果表中。

    请尝试使用此查询:

    SELECT ProjectNumber
    ,      ProductionNotes AS Shipment
    ,      PromiseDate AS "End"
    ,      Notes
    ,      MIN(WorkOrderNumber) AS "Work Order"
    ,      Name AS "Sales Order"
    ,      PromiseDate
    ,      Quantity
    ,      PartName
    FROM   Database.dbo.daWorkOrders
    WHERE  StatusTypeID = 3
    GROUP BY ProjectNumber, ProductionNotes, PromiseDate, Note, Name, PromiseDate, Quantity, PartName
    ORDER BY PromiseDate ASC;
    

    【讨论】:

    • 我收到了这个回复:The text, ntext, and image data types cannot be compared or sorted, except when using IS NULL or LIKE operator.
    • 有道理。我将以编程方式删除多余的行。谢谢
    • @MegaTron 此查询不会产生所需的结果,因为您正在对 PartName 和 Quantity 进行分组...
    【解决方案2】:

    我会使用带有分区子句的row_number() 窗口函数:over (partition by [ProjectNumber] order by [WorkOrderNumber]) 并过滤每个分区中的行号 = 1:

    with cte as (
        select 
           rn = row_number() over (partition by [ProjectNumber] order by [WorkOrderNumber])
           , *
        from Database.dbo.daWorkOrders
    )
    select * from cte
    where rn = 1;
    

    这将为您提供每个 ProjectNumber 的第一个 WorkOrder:

    rn  ProjectNumber   WorkOrder   Shipment    Start   End Quantity    PartName
    1   1234    1234-01 S-01    2015-09-01 00:00:01 2015-09-01 00:00:01 200 Part A
    1   2345    2345-01 S-01    2015-09-02 00:00:01 2015-09-02 00:00:01 12  Part A
    

    如果您的 WorkOrder 列是 text 类型,您可以将其转换为 varchar 以使分区工作:

    row_number() over (partition by [ProjectNumber] order by cast([WorkOrder] as varchar(20)))
    

    (20 可能不是正确的大小,根据需要调整)。

    【讨论】: