2016-11-20 4 views
2

Ich habe eine Tabelle namens Index der die Spalten id und value hat, wo id ein Autoinkrement Bigint und value ist ein varchar mit einem Wort Englisch.SQL Index-basierte Suche

Ich habe eine Tabelle mit dem Namen Search, die Beziehungen zu der Tabelle Index hat. Für jede Suche können Sie definieren, welche Indizes in einer Tabelle namens Article gesucht werden sollen. Die Tabelle Article hat ebenfalls Beziehungen zur Tabelle Index.

Die Tabellen, die die Beziehungen definieren sind:

Searches_Indexes mit Säulen id_search und id_index.

Articles_Indexes mit den Spalten id_article und id_index.

Ich möchte alle Artikel finden, die die gleichen Indizes der Suche enthalten.

Zum Beispiel: Ich habe ein Search mit Indizes laptop und dell, würde Ich mag alle Article s abzurufen, die beide Indizes enthalten, nicht nur eine.

Bisher habe ich dies:

SELECT ai.id_article 
FROM articles_indexes AS ai 

INNER JOIN searches_indexes AS si 
ON si.id_index = ai.id_index 

WHERE si.id_search = 1 

Wie kann ich meine SQL nur geben die Article s mit allen Index es eines Search?

Edit:

Beispieldaten:

Artikel:

id | name   | description   | ... 
1 | 'Dell Laptop' | 'New Dell Laptop...' | ... 
2 | 'HP Laptop' | 'Unused HP Laptop...' | ... 
... 

Suche:

id | name     | id_user | ... 
1 | 'Dell Laptop Search' | 5  | ... 

Index:

id | value 
1 | 'dell' 
2 | 'laptop' 
3 | 'hp' 
4 | 'new' 
5 | 'unused' 
... 

Articles_Indexes:

Article mit id 1 (dem Dell-Laptop) hat das Index es 'dell', 'Laptop', 'new'.

Article mit id 2 (der hp laptop) hat die Index es "laptop", "hp", "unbenutzt".

id_article | id_index 
1   | 1 
1   | 2 
1   | 4 
... 
2   | 2 
2   | 3 
2   | 5 
... 

Searches_Indexes:

Search mit id 1 enthält nur 2 Index es, 'dell' und 'Laptop':

id_search | id_index 
1   | 1 
1   | 2 

Erforderliche Ausgabe:

id_article 
1 
+2

Tabellen namens Suche und Index ... Welche anderen Tabellen haben Sie - Spalte, wo, wählen und Wert? – jarlh

+0

Aktualisiert, um es ein wenig klarer zu machen. Ich habe zwei Beziehungstabellen 'Search_Indexes' und' Articles_Indexes', die grundsätzlich definieren, welche Suchbegriffe welche Indizes haben und welche Artikel welche Indizes haben. –

+0

[bearbeiten] Sie Ihre Frage und fügen Sie einige Beispieldaten und die erwartete Ausgabe basierend auf diesen Daten hinzu. [_Formatted_] (http://dba.stackexchange.com/help/formatting) ** Text ** bitte, [keine Screenshots] (http://meta.stackoverflow.com/questions/285551/why-may-i -nicht-upload-images-of-code-auf-so-wenn-eine-Frage stellen/285557 # 285557) –

Antwort

1

Wenn ich richtig verstehe, wollen Sie Aggregation und eine HAVING Klausel. Unter der Annahme, es keine doppelten Einträge in den Indizes Tabellen:

SELECT ai.id_article 
FROM articles_indexes ai INNER JOIN 
    searches_indexes si 
    ON si.id_index = ai.id_index 
WHERE si.id_search = 1 
GROUP BY ai.id_article 
HAVING COUNT(*) = (SELECT COUNT(*) FROM searches_indexes si2 WHERE si2.id_search = 1); 

Dadurch wird die Anzahl der Spiele zählt und sicher macht es entspricht der Zahl, die Sie suchen.

Ich sollte das hinzufügen. Wenn Sie alle Suchvorgänge in der gleichen Zeit suchen wollte, würde ich geneigt sein, dies zu schreiben, wie:

SELECT si.id_search, ai.id_article 
FROM articles_indexes ai INNER JOIN 
    (SELECT si.*, COUNT(*) OVER (PARTITION BY si.id_index) as cnt 
     FROM searches_indexes si 
    ) si 
    ON si.id_index = ai.id_index 
GROUP BY si.id_search, ai.id_article, si.cnt 
HAVING COUNT(*) = si.cnt; 
0

Sie Arrays vergleichen können. Hier ein Beispiel:

create table article_index(id_article int, id_index int); 
create table search_index(id_search int, id_index int); 

insert into article_index 
select generate_series(1,2), generate_series(1,10); 
insert into search_index 
select generate_series(1,2), generate_series(1,4); 

select 
    id_article 
from article_index 
group by id_article 
having array_agg(id_index) @> (select array_agg(id_index) from search_index where id_search = 2); 

Learn more über Arrays in Postgres.