为除一列以外的所有列选择“区别”或“分组依据”

时间:2014-10-02 15:43:28

标签: sql performance group-by duplicates distinct

所以我很难接受我需要采取的方法。在这里有一个问题:

    select type_type,
        RCD_REASON,
        rc.description,
        MATERIAL_ID,
        USERID,
        DATETIME_SCRAPPED,
        ORDER_NUMBER,
        TRIMDATE,
        SUBSTR(SALES_ORDER,3,8) || '-' || SUBSTR(SOL_LINE_NUMBER,3,4) AS SalesOrder,
        QTY,
        COMPONENT_MATERIAL_ID 
from WORKCELL.history hh 
inner join WORKCELL.reason_codes rc
  on hh.rcd_reason = rc.reason
where rc.type_type in ('FAB','TRM') AND TO_CHAR(DATETIME_SCRAPPED,'YYYYMMDD') between to_char(:FromDate,'YYYYMMDD') AND to_char(:ToDate,'YYYYMMDD')
order by 1,2,9

根据SSRS中的两个日期参数提取记录。但是,问题是我不想要SALES_ORDER或ORDER_NUMBER的重复记录。我意识到我不能将Select Distinct用于我当前的查询,因为从技术上讲,它们都是基于DATETIME_SCRAPPED的,因为它还包括时间。组织此查询以获取我指定的所有行的最佳方法是什么,并且没有基于这两列的重复项?

3 个答案:

答案 0 :(得分:0)

它会是什么样的?

   select type_type,
        RCD_REASON,
        rc.description,
        MATERIAL_ID,
        USERID,
        (MAX)DATETIME_SCRAPPED as DATETIME_SCRAPPED,
        ORDER_NUMBER,
        TRIMDATE,
        SUBSTR(SALES_ORDER,3,8) || '-' || SUBSTR(SOL_LINE_NUMBER,3,4) AS SalesOrder,
        QTY,
        COMPONENT_MATERIAL_ID 
from WORKCELL.history hh 
inner join WORKCELL.reason_codes rc
  on hh.rcd_reason = rc.reason
where rc.type_type in ('FAB','TRM') AND TO_CHAR(DATETIME_SCRAPPED,'YYYYMMDD') between to_char(:FromDate,'YYYYMMDD') AND to_char(:ToDate,'YYYYMMDD')
Group By  type_type,
        RCD_REASON,
        rc.description,
        MATERIAL_ID,
        USERID,
        ORDER_NUMBER,
        TRIMDATE,
        SalesOrder,
        QTY,
        COMPONENT_MATERIAL_ID 
order by 1,2,9

我在SSRS中得到的结果如下所示,在此表下面是我希望它看起来的样子。

       QTY Fabric/Pc      Cut For When                Prd Ord      Sched    Sales Ord     Name 
>        1 906700021-5F72 T500173 09/30/2014 07:36:37 001038881084 20140929 05594568-4170 rg 
>        2 906700021-5F72 T500173 09/30/2014 06:22:12 001038881084 20140929 05594568-4170 rg 
>        2 906700021-5F72 T500175 09/30/2014 02:04:07 001038881052 20140929 05594568-4210 rg 
>        1 906700021-5F72 T500175 09/30/2014 10:45:42 001038881052 20140929 05594568-4210 rg 
>        1 906700021-5F72 T500176 09/30/2014 07:13:45 001038881057 20140929 05594568-4240 rg

我希望它只返回:

       QTY Fabric/Pc      Cut For When                Prd Ord      Sched    Sales Ord     Name 
>        1 906700021-5F72 T500173 09/30/2014 07:36:37 001038881084 20140929 05594568-4170 rg 
>        2 906700021-5F72 T500175 09/30/2014 02:04:07 001038881052 20140929 05594568-4210 rg 
>        1 906700021-5F72 T500176 09/30/2014 07:13:45 001038881057 20140929 05594568-4240 rg

在第二个数据集中,已删除具有相同Prd Ord和Sales Ord的行,并且最近的时间用于重复行。

答案 1 :(得分:0)

你可能不需要加入语句中的所有条件...只是日期和唯一的id字段...如果可以,尽量不要加入字符串。不过,我现在没有时间对其进行整理。

create table history (
   history_id    int auto_increment primary key, 
   fabric_pc     varchar(20), 
   cut_for       varchar(20),
   prod_ord      varchar(20),
   sales_ord     varchar(20),  
   quantity      int,
   datetime_scrapped datetime 
);

insert into history (history_id, fabric_pc, cut_for, datetime_scrapped, prod_ord,  sales_ord, quantity) values (null,'906700021-5F72','T500173','2014-09-30 07:36:37','001038881084','05594568-4170',1);
insert into history (history_id, fabric_pc, cut_for, datetime_scrapped, prod_ord,  sales_ord, quantity) values (null,'906700021-5F72','T500173','2014-09-30 06:22:12','001038881084','05594568-4170',2);

insert into history (history_id, fabric_pc, cut_for, datetime_scrapped, prod_ord,  sales_ord, quantity) values (null,'906700021-5F72','T500175','2014-09-30 02:04:07','001038881052','05594568-4210',2);
insert into history (history_id, fabric_pc, cut_for, datetime_scrapped, prod_ord,  sales_ord, quantity) values (null,'906700021-5F72','T500175','2014-09-30 10:45:42','001038881052','05594568-4210',1);

insert into history (history_id, fabric_pc, cut_for, datetime_scrapped, prod_ord,  sales_ord, quantity) values (null,'906700021-5F72','T500176','2014-09-30 07:13:45','001038881057','05594568-4240',1); 


select   max_dt_tbl.*, history.quantity 
from     history 
         join (select   fabric_pc, cut_for, prod_ord, sales_ord, 
                        max(datetime_scrapped) as max_datetime_scrapped
               from     history 
               -- put where conditions here 
               group    by fabric_pc, cut_for, prod_ord, sales_ord
               ) as max_dt_tbl
            on history.fabric_pc = max_dt_tbl.fabric_pc and 
               history.cut_for   = max_dt_tbl.cut_for   and
               history.prod_ord  = max_dt_tbl.prod_ord  and
               history.sales_ord = max_dt_tbl.sales_ord and 
               history.datetime_scrapped=max_dt_tbl.max_datetime_scrapped

返回......

+----------------+---------+--------------+---------------+-----------------------+----------+
| fabric_pc      | cut_for | prod_ord     | sales_ord     | max_datetime_scrapped | quantity |
+----------------+---------+--------------+---------------+-----------------------+----------+
| 906700021-5F72 | T500173 | 001038881084 | 05594568-4170 | 2014-09-30 07:36:37   |        1 |
| 906700021-5F72 | T500175 | 001038881052 | 05594568-4210 | 2014-09-30 10:45:42   |        1 |
| 906700021-5F72 | T500176 | 001038881057 | 05594568-4240 | 2014-09-30 07:13:45   |        1 |
+----------------+---------+--------------+---------------+-----------------------+----------+

因为......

mysql> select * from history;
+------------+----------------+---------+--------------+---------------+----------+---------------------+
| history_id | fabric_pc      | cut_for | prod_ord     | sales_ord     | quantity | datetime_scrapped   |
+------------+----------------+---------+--------------+---------------+----------+---------------------+
|          1 | 906700021-5F72 | T500173 | 001038881084 | 05594568-4170 |        1 | 2014-09-30 07:36:37 |
|          2 | 906700021-5F72 | T500173 | 001038881084 | 05594568-4170 |        2 | 2014-09-30 06:22:12 |
|          3 | 906700021-5F72 | T500175 | 001038881052 | 05594568-4210 |        2 | 2014-09-30 02:04:07 |
|          4 | 906700021-5F72 | T500175 | 001038881052 | 05594568-4210 |        1 | 2014-09-30 10:45:42 |
|          5 | 906700021-5F72 | T500176 | 001038881057 | 05594568-4240 |        1 | 2014-09-30 07:13:45 |
+------------+----------------+---------+--------------+---------------+----------+---------------------+
5 rows in set (0.00 sec)

让我知道这是不是你想要的......(根据我使用的数据...)

  • 第1行和第2行除日期时间和数量外都相同。第1行是最近的,所以它被返回。
  • 第3行和第4行除日期时间和数量外都相同。第4行是最近的,所以它被返回。
  • 第5行没有任何竞争行,因此返回。

答案 2 :(得分:0)

这通常使用窗口函数来解决(您没有指定DBMS,但这是由各种DBMS支持的ANSI标准SQL)。

select *
from (
    select type_type,
           RCD_REASON,
           rc.description,
           MATERIAL_ID,
           USERID,
           DATETIME_SCRAPPED,
           ORDER_NUMBER,
           TRIMDATE,
           SUBSTR(SALES_ORDER,3,8) || '-' || SUBSTR(SOL_LINE_NUMBER,3,4) AS SalesOrder,
           QTY,
           COMPONENT_MATERIAL_ID , 
           row_number() over (partition by  material_id, order_number order by DATETIME_SCRAPPED desc) as rn

    from WORKCELL.history hh 
    inner join WORKCELL.reason_codes rc
      on hh.rcd_reason = rc.reason
    where rc.type_type in ('FAB','TRM') AND TO_CHAR(DATETIME_SCRAPPED,'YYYYMMDD') between to_char(:FromDate,'YYYYMMDD') AND to_char(:ToDate,'YYYYMMDD')
) t
where rn = 1
order by 1,2,9;

通过窗口定义中的order by in(partition by部分),如果有多个具有相同的material_id和order_number,则可以控制要返回的行。使用order by DATETIME_SCRAPPED desc会导致选择最新的"基于DATETIME_SCRAPPED