sql >> Database teknologi >  >> RDS >> Mysql

Filtrer rækker med flere store vektorer

Dette bruger konceptet med en cross join a.k.a. Cartesian Product (alle permutationer). Så dine arrays producerer en afledt tabel (i hukommelsen) med et rækkeantal på x*y*z , hvor disse x,y,z er størrelserne af arrays. Hvis du leverede arrays af størrelse 3,4 og 5, ville den afledte tabel have et rækkeantal på 3*4*5=60.

Din leverede array-matchup, der producerer en række, var kun 4*1*1=4

thing7 nedenfor er din hovedtabel, du søger. covering index burde få denne ting til at flyve selv med et væld af data i den. Et dækkende indeks er et, hvor den tilvejebragte information gives via indeksets b-træ-scanning, og at en dataside-læsning ikke er påkrævet. Hvorfor? Fordi de nødvendige data er i indekset. Og i dit tilfælde ekstremt tynd.

Tabellerne A B C er til brug som dine arrays.

Den eneste anden ting at sige er, at hver afledt tabel kræver et navn. Så vi gav den navnet xDerived i forespørgslen. Tænk på en afledt tabel som noget, der returneres og bruges i hukommelsen. Det er ikke et fysisk bord.

Skema

create table thing7
(   id int auto_increment primary key,
    A int not null,
    B int not null,
    C int not null,
    index(A,B,C) -- covering index (uber-thin, uber-fast)
);

insert thing7(A,B,C) values
(1,2,7),  
(1,2,8), 
(2,2,1), 
(1,3,1);

create table A
(   id int auto_increment primary key,
    value int
);
create table B
(   id int auto_increment primary key,
    value int
);
create table C
(   id int auto_increment primary key,
    value int
);

Test 1

truncate table A;
truncate table B;
truncate table C;
insert A (value) values (1),(2),(3),(4);
insert B (value) values (2);
insert C (value) values (7);

select t7.* 
from thing7 t7  
join 
(   select A.value as Avalue, B.value as Bvalue, C.value as Cvalue 
    from A 
    cross join B 
    cross join C 
    order by a.value,b.value,c.value 
) xDerived 
on xDerived.Avalue=t7.A and xDerived.Bvalue=t7.B and xDerived.Cvalue=t7.C; 
+----+---+---+---+
| id | A | B | C |
+----+---+---+---+
|  1 | 1 | 2 | 7 |
+----+---+---+---+

..

Test 2

truncate table A;
truncate table B;
truncate table C;
insert A (value) values (1);
insert B (value) values (2);
insert C (value) values (0);

select t7.*
from thing7 t7 
join
(   select A.value as Avalue, B.value as Bvalue, C.value as Cvalue
    from A
    cross join B
    cross join C
    order by a.value,b.value,c.value
) xDerived
on xDerived.Avalue=t7.A and xDerived.Bvalue=t7.B and xDerived.Cvalue=t7.C;
-- no rows returned

Det ville være meget nemt at omdanne dette til en sessionsbaseret søgning. Konceptet der er et, hvor de arrays, der skal søges (tabeller A B C), har en sessionskolonne. Det ville så lette samtidig brug af flere brugere. Men det er over-engineering af svaret, men spørg, hvis du vil have mere information om det.




  1. PHP Vælg med PDO Kald til en medlemsfunktion prepare() på en ikke-objekt fejl

  2. Sådan kopieres data fra en database/tabel til en anden database/tabel

  3. Oracle-forespørgsel til at samle QTY efter år - kun sidste 3 år

  4. MySQL - eksploder/opdel input til lagret procedure