0

假设我需要查询一家公司的员工。我有一个表格,“交易”,其中包含每笔交易的数据。

CREATE TABLE `transactions` (
  `transactionID` int(11) unsigned NOT NULL,
  `orderID` int(11) unsigned NOT NULL,
  `customerID` int(11) unsigned NOT NULL,
  `employeeID` int(11) unsigned NOT NULL, 
  `corporationID` int(11) unsigned NOT NULL,
  PRIMARY KEY (`transactionID`),
  KEY `orderID` (`orderID`),
  KEY `customerID` (`customerID`),
  KEY `employeeID` (`employeeID`),
  KEY `corporationID` (`corporationID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

查询此表中的员工相当简单,但有一个转折点:每个员工注册一次交易记录,因此每个订单可能有多个记录用于一个公司。

例如,如果公司 1 的员工 A 和 B 都参与向公司 2 出售吸尘器,则“交易”表中将有两条记录;每个员工一个,公司 1 两个。不过,这一定不会影响结果。来自公司 1 的交易,无论涉及多少员工,都必须被视为一项交易。

容易,我想。我将在派生表上进行连接,如下所示:

SELECT corporationID FROM transactions JOIN (SELECT DISTINCT orderID FROM transactions WHERE corporationID = 1) AS foo USING (orderID)

该查询返回与公司 1 进行交易的公司列表。这正是我所需要的,但它非常慢,因为 MySQL 无法使用公司 ID 索引来确定派生表。我了解 MySQL 中的所有子查询/派生表都是这种情况。

我还尝试单独查询 orderID 的集合并使用一个非常大的 IN() 子句(通常是 100 000+ 个 ID),但事实证明 MySQL 在使用非常大的 IN() 子句的索引时也存在问题结果查询时间没有改善。

有没有其他可用的选项,还是我都用尽了它们?

4

2 回答 2

1

如果我理解你的要求,你可以试试这个。

select distinct t1.corporationID
from transactions t1
where exists (
    select 1
    from transactions t2
    where t2.corporationID =  1
    and t2.orderID = t1.orderID)
and t1.corporationID != 1;

或这个:

select distinct t1.corporationID
from transactions t1
join transactions t2
on t2.orderID = t1.orderID
and t1.transactionID != t2.transactionID
where t2.corporationID = 1
and t1.corporationID != 1;
于 2010-01-19T07:56:22.047 回答
0

您的数据对我来说毫无意义,我认为您使用的是corporateID,其中您的意思是客户ID,因为您的查询根据orderID将事务表连接到corporationID = 1的事务表以获取corporateID ...那将是1,对吗?

您能否指定 customerID、employeeID 和corporateID 的含义?我怎么知道员工 A 和 B 来自公司 1 - 在这种情况下,公司 1 是公司 ID,公司 2 是客户,因此存储在客户 ID 中?

如果是这种情况,您只需要通过以下方式进行分组:

SELECT customerID
FROM transactions
WHERE corporationID = 1
GROUP BY customerID

(或者如果您希望每个订单一行而不是每个客户一行,则按 orderID 选择和分组。)

通过使用 group by,您忽略了除了employeeID 之外有多个重复记录的事实。

相反,返回所有已出售给公司 2 的公司。

SELECT corporationID
FROM transactions
WHERE customerID = 2
GROUP BY corporationID
于 2010-01-19T07:35:00.927 回答