Domanda

Diciamo che ho bisogno di interrogare i soci di una società. Ho una tabella, "operazioni", che contiene i dati su ogni transazione effettuata.

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;

E 'abbastanza semplice per interrogare questa tabella per i soci, ma c'è un colpo di scena: un record transazione viene registrata una volta per dipendente, e quindi non ci può essere più record per una società per ordine

.

Ad esempio, se i dipendenti A e B dalla società 1 sono stati entrambi coinvolti nella vendita di un aspirapolvere per società 2, ci sarebbero due record nella tabella "transazioni"; uno per ciascun dipendente, e sia per la società per azioni 1. Questo non deve influire sui risultati, però. Un mestiere da società 1, indipendentemente dal numero dei suoi dipendenti sono stati coinvolti, deve essere trattato come tale.

Facile, ho pensato. Mi rifarò una join su una tabella derivata, in questo modo:

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

La query restituisce un elenco di aziende che sono stati coinvolti nei traffici con società 1. Questo è esattamente quello che mi serve, ma è molto lento perché MySQL non è possibile utilizzare l'indice corporationID per determinare la tabella derivata. Capisco che questo è il caso per tutti i sottoquery / tabelle derivate in MySQL.

Ho anche cercato di interrogare una raccolta di OrderIDs separatamente e utilizzare un ridicolmente grande clausola () (typhically 100 000+ IDS), ma a quanto pare MySQL ha problemi con gli indici sulla ridicolmente grande IN () clausole come bene e di conseguenza il tempo di query non migliora.

Ci sono tutte le altre opzioni disponibili, o hanno li esausto entrambi?

È stato utile?

Soluzione

Se ho capito la vostra esigenza, si potrebbe provare questo.

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;

o questo:

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;

Altri suggerimenti

I suoi dati non ha senso per me, penso che si sta utilizzando corporationID dove intendi ID cliente a un certo punto in là, come la query unisce la tabella transazione al tavolo transazione per corporationID = 1 sulla base di orderID per ottenere i corporationIDs ... che sarebbe poi essere 1, giusto?

Si può specificare cosa significano il CustomerID, employeeID, e corporationIDs? Come faccio a sapere dipendenti A e B sono da corporation 1 -? In tal caso, è Corporation 1 il corporationID, e Corporation 2 è il cliente, e quindi memorizzati nella customerID

Se questo è il caso, è sufficiente fare un gruppo:

SELECT customerID
FROM transactions
WHERE corporationID = 1
GROUP BY customerID

(o selezionare e di gruppo da orderID se si desidera una riga per ogni ordine, invece di una riga per ogni cliente.)

Usando il gruppo da, si ignora il fatto che ci sono più record che sono duplicati, tranne per l'employeeID.

Al contrario, i rendimenti tutte le società che hanno venduto a società 2.

SELECT corporationID
FROM transactions
WHERE customerID = 2
GROUP BY corporationID
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top