2

我有一个大问题。谁能帮我一把?

我的第一个目标是:用查询语句过滤重复数据(选择不删除),即由于重复反馈,同一ServiceID的EndTime和Qos的各种条目。规则是只保留同一 ServiceID 的 Qos 最低的记录。如果有几条记录的 Qos 最低,则只保留这些记录中的任何一条。客户接受并更喜欢这种方案。在这个例子中,对于 ID=6,7 和 8,只保留 6 或 7。我在这里得到了这个目标的答案:

SELECT DISTINCT serviceid,tcid,endtime,qos 
FROM (SELECT * 
      FROM service 
      ORDER BY serviceid, qos, id) AS base 
GROUP BY serviceid

目标2:Qos=1 表示服务满意。每个技术支持工程师实现的每月满意服务总量称为“个人本月满意服务总量”。“本月个人总体满意服务”排名当月前2名的技术支持工程师称为“本月以来前2名”。如果他们足够优秀,每个月都有资格获得“本月以来的前2名”,那么他们可以被称为“优秀1级”。总而言之,这一步是计算“1 级优秀”。在此示例中,一月的“本月以来排名前 2”是 Andrew 和 Jacob,二月的“Top 2”是 Andrew、Dlyan 和 Jacob。因此,“一等奖”的荣誉称号授予了Andrew和Jacob(仅这2位录音师)。

请帮助我完成目标 2(最后我应该达到目标 4,最终目标),目标 2 的结果应该是

TCID
安德鲁
雅各布
说明:全年有一些技术服务数据(ServiceID、TCID、EndTime、QoS),ID是唯一的主键,因为有一些重复。

差点忘了说,只是提醒一下,客户端只接受SQL而不是数据库中的存储过程来实现它。我只需要查询语句,因为客户不允许我们写数据库。

 some data:
ServiceID ID TCID EndTime Qos
2000 2 雅各布 2011/1/1 2
2000 3 雅各布 2011/1/1 2
2001 4 雅各布 2011/1/1 2
2002 5 雅各布 2011/2/3 1
2003 6 泰勒 2011/1/4 1

数据结构:

  • ID:记录的唯一主键
  • ServiceID:某个服务的ID
  • TCID:技术支持工程师的ID
  • EndTime:服务的结束时间
  • Qos:服务质量(1满意;2一般;3不满意/不满意)。

DDL 和插入 SQL(mysql5):

CREATE TABLE `service` (
  `ServiceID` INTEGER(11) NOT NULL,
  `ID` INTEGER(11) NOT NULL ,
  `TCID` VARCHAR(40)  NOT NULL,
  `EndTime` DATE NOT NULL,
  `Qos` CHAR(1)  NOT NULL,
  PRIMARY KEY (`ID`),
  UNIQUE KEY `ID` (`ID`)
);
COMMIT;
INSERT INTO `service` (`ServiceID`, `ID`, `TCID`, `EndTime`, `Qos`) VALUES
  (2004, 9, 'Jacob', '2011-02-04', '1'),
  (2000, 2, 'Jacob', '2011-01-01', '2'),
  (2000, 3, 'Jacob', '2011-01-01', '2'),
  (2001, 4, 'Jacob', '2011-01-01', '2'),
  (2002, 5, 'Jacob', '2011-02-03', '1'),
  (2003, 6, 'Tyler', '2011-01-04', '1'),
  (2003, 7, 'Tyler', '2011-01-04', '1'),
  (2003, 8, 'Tyler', '2011-01-03', '2'),
  (2005, 10, 'Jacob', '2011-02-05', '1'),
  (2006, 11, 'Jacob', '2011-02-04', '2'),
  (2007, 12, 'Jacob', '2011-01-08', '1'),
  (2008, 13, 'Tyler', '2011-02-06', '1'),
  (2009, 14, 'Dylan', '2011-02-08', '1'),
  (2010, 15, 'Dylan', '2011-02-09', '1'),
  (2014, 16, 'Andrew', '2011-01-01', '1'),
  (2013, 17, 'Andrew', '2011-01-01', '1'),
  (2012, 18, 'Andrew', '2011-02-19', '1'),
  (2011, 19, 'Andrew', '2011-02-02', '1'),
  (2015, 20, 'Andrew', '2011-02-01', '1'),
  (2016, 21, 'Andrew', '2011-01-19', '1'),
  (2017, 22, 'Jacob', '2011-01-01', '1'),
  (2018, 23, 'Dylan', '2011-02-03', '1'),
  (2019, 24, 'Dylan', '2011-01-09', '1'),
  (2020, 25, 'Dylan', '2011-01-01', '1'),
  (2021, 26, 'Andrew', '2011-01-03', '1'),
  (2021, 27, 'Dylan', '2011-01-11', '1'),
  (2022, 28, 'Jacob', '2011-01-09', '1'),
  (2023, 29, 'Tyler', '2011-01-19', '1'),
  (2024, 30, 'Andrew', '2011-02-01', '1'),
  (2025, 31, 'Dylan', '2011-02-03', '1'),
  (2026, 32, 'Jacob', '2011-02-04', '1'),
  (2027, 33, 'Tyler', '2011-02-09', '1'),
  (2028, 34, 'Daniel', '2011-01-06', '1'),
  (2029, 35, 'Daniel', '2011-02-01', '1');
 COMMIT;

这是我的前 2 个目标,还有 2 个,我打算一个接一个地完成所有这些步骤。任何人都可以帮助实现第一个目标吗?我知道这很复杂,非常感谢您提前。

目标3:那么,计算“二等奖”(不包括“本月以来排名前2”的工程师)等于计算排名第三和第四的工程师。在这个例子中,“2 级杰出”是 Tyler。

目标4:最终目标是把“一等优秀”和“二等优秀”结合起来。结果将最终传输到报告进行渲染。我的数据集应该如下所示:

TCID       level
Andrew     top2
Jacob      top2
Tyler      top4

目标 1 的结果应该是这样的:

2000 2 雅各布 2011/1/1 2
2001 4 雅各布 2011/1/1 2
2002 5 雅各布 2011/2/3 1
2003 6 泰勒 2011/1/4 1
2004 9 雅各布 2011/2/4 1
2005 10 雅各布 2011/2/5 1
2006 11 雅各布 2011/2/4 2
2007 12 雅各布 2011/1/8 1
2008 13 泰勒 2011/2/6 1
2009 14 迪拉 2011/2/8 1
2010 15 迪拉 2011/2/9 1
2011 19 安德鲁 2011/2/2 1
2012 18 安德鲁 2011/2/19 1
2013 17 安德鲁 2011/1/1 1
2014 16 安德鲁 2011/1/1 1
2015 20 安德鲁 2011/2/1 1
2016 21 安德鲁 2011/1/19 1
2017 22 雅各布 2011/1/1 1
2018 23 迪拉 2011/2/3 1
2019 24 迪拉 2011/1/9 1
2020 25 迪拉 2011/1/1 1
2021 26 安德鲁 2011/1/3 1
2022 28 雅各布 2011/1/9 1
2023 29 泰勒 2011/1/19 1
2024 30 安德鲁 2011/2/1 1
2025 31 迪拉 2011/2/3 1
2026 32 雅各布 2011/2/4 1
2027 33 泰勒 2011/2/9 1
2028 34 丹尼尔 2011/1/6 1
2029 35 丹尼尔 2011/2/1 1
4

2 回答 2

1

最后,我找到了一个使用集算器来解决这个问题的解决方案。集算器是我找到的唯一解决方案。是的,它可以返回一个 resultSet 对象并由报告工具调用(我使用的是 Jasper)。但我仍然需要一个 SQL 解决方案。所以,请告诉我是否有任何 SQL 解决方案。感谢您的回复。

集算器解决方案

以下是有关此解决方案的一些信息:http: //www.esproc.com/tour/what-is-esproc.html

或者这里是一个 SQL Server 解决方案(但不适合 mysql):http ://social.msdn.microsoft.com/Forums/en-US/transactsql/thread/e11c754d-559e-4eb7-9682-e998ea3387d9

希望这可以帮助遇到同样麻烦的人。

于 2012-04-23T05:49:26.330 回答
0

此查询打算为每个 SERVICE_ID 仅选择一行,它将仅包括相应 SERVICE_ID 的 QO 最低的记录,即使这样,它也通过仅选择一个来避免多行。正如您提到的“保留这些记录中的任何一条”,我使用 rowid 随机选择一条记录

您可以针对此条件运行选择查询,以查看提取的记录是否适合您,然后再运行删除命令


DELETE FROM SERVICE S
 WHERE S.SERVICEID IN (SELECT DISTINCT S.SERVICEID
                         FROM SERVICE S
                        GROUP BY S.SERVICEID
                       HAVING COUNT(*) > 1)
   AND S.QOS =
       (SELECT MIN(S1.QOS) FROM SERVICE S1 WHERE S1.SERVICEID = S.SERVICEID)
   AND ROWID =
       (SELECT MIN(ROWID) FROM SERVICE S1 WHERE S1.SERVICEID = S.SERVICEID)

Hope it helps

于 2012-04-17T08:18:55.003 回答