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 回登録されるため、注文ごとに 1 つの企業に対して複数のレコードが存在する場合があります。

たとえば、企業 1 の従業員 A と B の両方が企業 2 への掃除機の販売に関与していた場合、"transactions" テーブルには 2 つのレコードが存在します。従業員ごとに 1 つ、企業 1 には両方。ただし、これは結果に影響を与えてはなりません。企業 1 からの取引は、関与した従業員の数に関係なく、1 つとして扱われなければなりません。

簡単だと思いました。次のように、派生テーブルで結合を作成します。

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

クエリは、企業 1 との取引に関与した企業のリストを返します。これはまさに私が必要としているものですが、MySQL は、corporationID インデックスを使用して派生テーブルを決定できないため、非常に遅くなります。これは、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

Your data makes no sense to me, I think you are using corporationID where you mean customer ID at some point in there, as your query joins the transaction table to the transaction table for corporationID=1 based on orderID to get the corporationIDs...which would then be 1, right?

Can you please specify what the customerID, employeeID, and corporationIDs mean? How do I know employees A and B are from corporation 1 - in that case, is corporation 1 the corporationID, and corporation 2 is the customer, and so stored in the customerID?

If that is the case, you just need to do a group by:

SELECT customerID
FROM transactions
WHERE corporationID = 1
GROUP BY customerID

(Or select and group by orderID if you want one row per order instead of one row per customer.)

By using the group by, you ignore the fact that there are multiple records that are duplicate except for the employeeID.

Conversely, to returns all corporations that have sold to corporation 2.

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