【发布时间】:2018-07-28 14:07:21
【问题描述】:
我继承了一个结构很差的数据库,我的任务是从中获取有用的信息。我有两个表,Transactions 和 CodeDefinitions。
这是事务表的简化示例
ID (primary key)
CodeName (varchar(50))
Description(varchar(255)
TranDate (datetime)
Amount (money)
CodeDefinitions 表的简化结构
ID (primary key)
Name (varchar(50))
Description (varchar(255))
两个表中的示例数据
事务表(包含 500,000 行事务)
ID CodeName Description TranDate Amount
510348 HRCUT Haircut 2017-11-02 30.00
510349 RINSE Rinse - Extra Deluxe 2017-11-02 45.00
510350 PERM Luxury Perm 2017-11-02 80.00
510351 HRCUT Haircut 2017-11-02 30.00
CodeDefinitions 表(2000 行只有 SKU)
ID Name Description
684 RINSE Rinse - Extra Deluxe
686 HRCUT Haircut
730 PERM Luxury Perm
2203 HRCUT Haircut (note the duplicate name and description!)
以前的数据库开发人员没有费心在 CodeDefinitions.Code 上设置 UNIQUE 约束,甚至对 Transactions.Code 设置 FK 约束。所以这意味着用户可以输入相同的 CodeDefinitions.Name,唯一的区别是 CodeDefinitions.ID。由于 Transactions 表仅包含特定 CodeDefinition 的名称和描述,而不包含 ID,因此尝试过滤掉重复项非常麻烦
我想要做的是能够通过在 Transactions.CodeID 上加入以消除重复,准确地计算给定时间日期已售出多少理发的金额。如果两个 SKU 具有相同的名称,请选择最高的 CodeDefinitions.ID。如果可能的话,我想避免使用 DISTINCT、GROUP BY 或 MAX,因为它们将查询执行时间从 5 秒缩短到 5 分钟(除非我编写查询的方式有问题,否则我不太熟悉MySQL 优化器)
我曾尝试Left JOIN on t.CodeName = cd.Name,但这会将所有CodeDefinitions.ID 返回为NULL。我需要能够SELECT the CodeDefinitions.ID进行过滤。
我的查询:
SELECT
t.ID AS TranID
, t.CodeName AS ProcedureCode
, cd.ID AS CodeID
, Description
, t.TranDate
, t.Amount
FROM transactions t
LEFT OUTER JOIN CodeDefinitions cd ON (T.Description = cd.Description)
WHERE TranDate BETWEEN '2017-11-1' AND '2017-11-31'
预期结果:
TranID ProcedureCode CodeID Description TranDate TranAmt
510348 HRCUT 2203 Haircut 2017-11-02 30.00
510349 RINSE 684 Rinse - Extra Deluxe 2017-11-02 45.00
510350 PERM 730 Luxury Perm 2017-11-02 80.00
510351 HRCUT 2203 Haircut 2017-11-02 30.00
实际结果:
TranID ProcedureCode CodeID Description TranDate TranAmt
510348 HRCUT 686 Haircut 2017-11-02 30.00
510348 HRCUT 2203 Haircut 2017-11-02 30.00
510349 RINSE 684 Rinse - Extra Deluxe 2017-11-02 45.00
510350 PERM 730 Luxury Perm 2017-11-02 80.00
510351 HRCUT 686 Haircut 2017-11-02 30.00
510351 HRCUT 2203 Haircut 2017-11-02 30.00
你如何摆脱这些重复并在每组重复中选择最高的 CodeID?
【问题讨论】:
标签: mysql sql database duplicates left-join