基于复杂联接计数的MySQL更新列
我正在用一个相当复杂的数据库模式构建一个报告。我有以下表格(为简洁起见简化) 零件有两个标识符:零件号和CLEI 所以这是同一部分:基于复杂联接计数的MySQL更新列,mysql,sql,join,count,sql-update,Mysql,Sql,Join,Count,Sql Update,我正在用一个相当复杂的数据库模式构建一个报告。我有以下表格(为简洁起见简化) 零件有两个标识符:零件号和CLEI 所以这是同一部分: -克莱:enbyaaaaa -零件号:NT9X 搜索进入search_数据表,用户可以通过partNumber、CLEI或两者进行搜索。因此,对于上面列出的零件,您可以在search_数据中看到该零件已被搜索了4次(ID 1、2、3和4) 我需要使用该零件号或CLEI的搜索次数更新分析表的num_searches列 因此,更新后,分析表应如下所示: -------
-克莱:enbyaaaaa
-零件号:NT9X 搜索进入search_数据表,用户可以通过partNumber、CLEI或两者进行搜索。因此,对于上面列出的零件,您可以在search_数据中看到该零件已被搜索了4次(ID 1、2、3和4) 我需要使用该零件号或CLEI的搜索次数更新分析表的num_searches列 因此,更新后,分析表应如下所示:
--------------------------------------------
id partNumber clei num_searches
--------------------------------------------
1 NT9X ENBYAAAAAA 4
2 EFGH EEEFFHI 0
3 NT9X null 4
4 null ENBYAAAAAA 4
我为此创建了一个有效的联接
SELECT *
FROM analytics_data a
join search_data s
on
case when a.partNumber is not null and a.partNumber != '' THEN a.partNumber = s.partNumber END
OR
case when a.clei is not null and a.clei != '' THEN a.clei = s.clei END
我使用案例陈述来解释这一事实,即两个表中可能都有partNumber和CLEI,也可能没有。当clei在analytics中为NULL时,一个简单的A.clei=s.clei语句将在搜索中为每一行提供一个NULL的clei,而不考虑零件号
这一困境正是导致更新困难的原因。我提出了这个更新声明。我不确定它是否有效,因为它不会结束。我在几分钟后杀死了它,因为这不是一个可接受的运行时
update analytics a
set a.num_searches =
(
select count(*) from search_data s where
(case when a.partNumber is not null and a.partNumber != ''
THEN a.partNumber = s.partNumber END
OR
case when a.clei is not null and a.clei != '' THEN a.clei =
s.clei END)
)
我不知道接下来该怎么办。这似乎是一项简单的任务,但我厌倦了把头撞在桌子上
有什么想法吗
===========================================================================================================================
解决Nick提出的解决方案的其他细节。
我关心的是,这些部分需要大量的迭代。零件可以有一个基本代码,如“NT9X”,再加上各种族代码(2个字符),再加上另一种特征代码(2个以上字符)
所以我们可以
NT9X
NT9XAB
NT9XBB
NT9XABAA
NT9XABBB
等等。所有部件都是相同的通用部件,但功能略有不同。还有很多零件号/CLEI组合。同一零件号可以有多个CLEI代码,反之亦然
因此,我们被迫执行许多类似于的查询。如果我想得到NT9X部分的所有引号,我有一个类似于
SELECT * FROM part_quotes WHERE partNumber LIKE 'NT9X%';
它适用于1部分。但对于像现在这样的例子,我有一个6000多个部分的列表,我需要来自十几个不同表的数据来生成一个报告,用一个查询是不可能的
因此,在您的场景中,我必须对part_numbers表执行类似于的查询,以获得所有潜在的part匹配。然后,我必须在part_id的表连接中使用IN子句
如果不进行测试,我不知道它的效率是高还是低
我有很多存储零件信息的表格。像
vendor_quotes
internal_quotes
search_results
search_data
sales_history
repair_pricing
pricing
purchase_history
expenses
还有更多。试图构建一个报告,在这个报告中,我必须对如此多的表和聚合数据进行通配符搜索,这是一个相当令人头痛的问题。我肯定需要一个更好的方法来实现它,并将在不久的将来测试您的解决方案 您的代码似乎太复杂了,但我认为它应该可以工作。这个版本很简单:
update analytics a
set a.num_searches = (select count(*)
from search_data s
where a.partNumber = s.partNumber or
a.clei = s.clei
);
您的数据没有空格,因此没有理由检查它们
但是,正如您所注意到的,性能相当差。相反,让我们分两部分来做。如果零件号相同,然后clei
与零件号不匹配:
update analytics a
set a.num_searches = ((select count(*)
from search_data s
where a.partNumber <=> s.partNumber
) +
(select count(*)
from search_data s
where not a.partNumber <=> s.partNumber and
a.clei = s.clei
)
);
更新分析a
设置a.num_searches=((选择count(*)
从搜索_数据
其中a.零件号s.零件号
) +
(选择计数(*)
从搜索_数据
其中不是a.零件号s.零件号和
a、 clei=s.clei
)
);
这个版本应该能够利用
search\u数据(partNumber,clei)
和search\u数据(clei,partNumber)
您的代码似乎太复杂了,但我认为它应该可以工作。这个版本很简单:
update analytics a
set a.num_searches = (select count(*)
from search_data s
where a.partNumber = s.partNumber or
a.clei = s.clei
);
您的数据没有空格,因此没有理由检查它们
但是,正如您所注意到的,性能相当差。相反,让我们分两部分来做。如果零件号相同,然后clei
与零件号不匹配:
update analytics a
set a.num_searches = ((select count(*)
from search_data s
where a.partNumber <=> s.partNumber
) +
(select count(*)
from search_data s
where not a.partNumber <=> s.partNumber and
a.clei = s.clei
)
);
更新分析a
设置a.num_searches=((选择count(*)
从搜索_数据
其中a.零件号s.零件号
) +
(选择计数(*)
从搜索_数据
其中不是a.零件号s.零件号和
a、 clei=s.clei
)
);
这个版本应该能够利用
search\u数据(partNumber,clei)
和search\u数据(clei,partNumber)
这是数据库正常化的经典参数。如果您有这样一个表零件号
:
CREATE TABLE part_numbers
(id INT, `partNumber` VARCHAR(4), `clei` VARCHAR(10));
INSERT INTO part_numbers VALUES
(1, 'NT9X', 'ENBYAAAAAA'),
(2, 'EFGH', 'EEEFFHI');
SELECT * FROM part_numbers
id partNumber clei
1 NT9X ENBYAAAAAA
2 EFGH EEEFFHI
3 NNTM EGFEDGF
id part_id searchDate
1 1 2017-10-15
2 1 2017-11-11
3 1 2017-11-12
4 1 2017-11-15
5 3 2017-11-15
您将search\u data
和analytics
中的partNumber
和clei
字段替换为part\u id
字段,该字段引用了part\u number
中的id
,因此,例如search\u data
将如下所示:
CREATE TABLE part_numbers
(id INT, `partNumber` VARCHAR(4), `clei` VARCHAR(10));
INSERT INTO part_numbers VALUES
(1, 'NT9X', 'ENBYAAAAAA'),
(2, 'EFGH', 'EEEFFHI');
SELECT * FROM part_numbers
id partNumber clei
1 NT9X ENBYAAAAAA
2 EFGH EEEFFHI
3 NNTM EGFEDGF
id part_id searchDate
1 1 2017-10-15
2 1 2017-11-11
3 1 2017-11-12
4 1 2017-11-15
5 3 2017-11-15
那么您的更新查询将是:
UPDATE analytics a
SET num_searches = (SELECT COUNT(s.id) FROM search_data s WHERE s.part_id = a.part_id)
这将向您展示如何转换表格以使您的生活更轻松
假设你不能(或不想)改变你的表格结构,生活就会变得更加困难。您可以通过此查询()生成分析应为的表:
输出:
id partnumber clei num_searches
1 NT9X ENBYAAAAAA 4
2 EFGH EEEFFHI 0
3 NT9X (null) 4
4 (null) ENBYAAAAAA 4
id partnumber clei num_searches
1 NT9X ENBYAAAAAA 4
2 EFGH EEEFFHI 0
3 NT9X (null) 4
4 (null) ENBYAAAAAA 4
因此更新查询变为(注意,我们必须连接子查询,因为我们不能在集合子句中使用包含更新表的子查询)():
输出:
id partnumber clei num_searches
1 NT9X ENBYAAAAAA 4
2 EFGH EEEFFHI 0
3 NT9X (null) 4
4 (null) ENBYAAAAAA 4
id partnumber clei num_searches
1 NT9X ENBYAAAAAA 4
2 EFGH EEEFFHI 0
3 NT9X (null) 4
4 (null) ENBYAAAAAA 4
这是一个clas