sql >> Database >  >> RDS >> Mysql

Filter rijen met verschillende grote vectoren

Dit gebruikt het concept van een cross join aka cartesiaans product (alle permutaties). Dus je arrays produceren een afgeleide tabel (in het geheugen) met een rijtelling van x*y*z , waarbij die x,y,z de grootte van de arrays zijn. Als u arrays van de grootte 3,4 en 5 opgeeft, zou de afgeleide tabel een rijtelling hebben van 3*4*5=60.

Uw geleverde array-matchup die een rij produceert, was slechts 4*1*1=4

thing7 hieronder is uw hoofdtabel die u zoekt. De covering index zou dit ding moeten laten vliegen, zelfs met een hoop gegevens erin. Een dekkende index is er een waarin de verstrekte informatie wordt gegeven via de b-tree-scan van de index en waarbij het lezen van een gegevenspagina niet vereist is. Waarom? Omdat de benodigde gegevens in de index staan. En in jouw geval extreem dun.

Tabellen A B C zijn voor gebruik als uw arrays.

Het enige andere om te zeggen is dat elke afgeleide tabel een naam vereist. Dus gaven we het de naam xDerived in de vraag. Beschouw een afgeleide tabel als iets dat wordt geretourneerd en in het geheugen wordt gebruikt. Het is geen fysieke tafel.

Schema

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

Het zou heel gemakkelijk zijn om dit om te zetten in een sessiegebaseerde zoekopdracht. Het concept daar is er een waarin de te doorzoeken arrays (tabellen A B C) een sessiekolom hebben. Het zou dan gelijktijdig gebruik door meerdere gebruikers mogelijk maken. Maar dat is over-engineering van het antwoord, maar vraag of je daar meer informatie over wilt.




  1. Bericht 28000:geen pg_hba.conf-invoer voor host \xx.xxx.xxx.xxxx\, gebruiker \Gebruiker, database \databasenaam\, SSL uit

  2. Kan ik een aangepast datumformaat krijgen voor plukken (lijsten) op Laravel5?

  3. Ik heb geen toegang tot de onbewerkte PDO-instantie in Laravel 5

  4. MySQL SELECT rijen die overeenkomen met Array?