2017-11-06 2 views
3

Ich habe drei Tabellen (SQLFiddle with tables created)MySQL Update-Reihen mit Doppel LEFT JOIN, die Begrenzung ersten Spiel

enter image description here

orange Text ist, was ich durch den Vergleich mit Products.name Filters.filter erhalten müssen.

habe ich herausgefunden, dass String Spiel wie dies getan werden kann:

on Products.name LIKE CONCAT('%',Filters.filter,'%'); 

Ich brauche nur die erste Übereinstimmung mit dem Filter verwendet werden. Also passt "Pilzsuppe" zu "Suppe" und nicht zu "Pilz".

Was ist der beste Ansatz für diese Aufgabe?

Eine getestete SQLFiddle-Verbindung, wenn möglich, bitte.

Was ich versucht: (fühlen sich frei, alles unter überspringen)

Versuchte Doppel beitreten:

update Products 
left join Filters on Products.name LIKE CONCAT('%',Filters.filter,'%') 
join Categories on Filters.category_name = Categories.name 
set Products.category_id = Categories.id, Products.filter = Filters.filter; 

Aber das ist nicht in ersten Spiel verwendet wird, führt, weil zuerst beitreten zurückgegeben alle Filter entspricht (mehrere Zeilen pro 1 Produkt), und nach dem zweiten Beitritt Kategorien sind von der letzten Übereinstimmung.

Zum Beispiel: Pilzsuppe kam in die Kategorie "Pilz-Zutaten" statt in "Suppe \ Mahlzeiten".

versuchte auch beitreten + Bestellung von:

select Products.name, Filters.* 
from Products 
left join Filters on Products.name LIKE CONCAT('%',Filters.filter,'%') 
group by Products.name; 

Dies gibt das erste Spiel pro Produkt als ich brauchte, aber ich kann ein zweiter von links kommen in derselben Abfrage nicht, weder kann ich " Gruppieren nach "nach" update "-Funktion statt" select "arbeiten.

Denn wenn sqlfiddle kollabiert:

CREATE TABLE Products 
(
    `name` varchar(30), 
    `category_name` varchar (30), 
    `category_id` int 
); 

INSERT INTO Products (`name`) 
VALUES ('Mushrooms'), ('Can of mushrooms'), 
     ('Can of soup'), ('Mushroom soup'), 
     ('Tomato soup'), ('Tomato'); 

CREATE TABLE Filters 
(
    `filter` varchar(30), 
    `category_name` varchar(30) 
); 

INSERT INTO Filters (`filter`, `category_name`) 
VALUES ('Can of', 'Canned food'), ('Soup', 'Meals'), 
     ('Mushroom', 'Ingredients'), ('Tomato', 'Ingredients'); 

CREATE TABLE Categories 
(
    `id` int, 
    `name` varchar(30) 
); 

INSERT INTO Categories (`id`, `name`) 
VALUES (1, "Canned food"), (2, 'Ingredients'), (3, 'Meals'); 
+1

Wow, so schön, tatsächlich solche Bemühungen in Richtung [mcve] zu sehen. – philipxy

+0

@philipxy Danke! Die Erstellung einer einfachen Problemstichprobe kommt allen zugute: demjenigen, der Schwierigkeiten hat, denen, die helfen können, und denen, die diese Frage in Zukunft lesen werden. Außerdem löse ich oft das Problem, bevor ich hier schreibe, nur indem ich versuche, einen einfachen Testfall zu erstellen :) – Trost

Antwort

2

Sie haben die Aufgabe, ganz einfach, mit Ihrem sqlfiddle sowie Ihr Versuch, das Problem mit Select-Abfrage zu lösen.

Es funktioniert wie Sie wollen Ich denke, und alles, was ich tun muss, ist eine weitere linke Join mit Kategorie Tabelle hinzufügen (IDK, warum Sie Kategorie nicht beitreten konnten, wie es richtig funktioniert).

So. Ich habe Ihre Select-Abfrage wie folgt bearbeitet:

select Products.name, Filters.*,Categories.id from Products 
left join Filters 
on Products.name LIKE CONCAT('%',Filters.filter,'%') 
left join Categories 
on Categories.name = Filters.category_name 
GROUP BY Products.name; 

Sie erhalten die gewünschten Ergebnisse mit dieser Abfrage.

Um nun Products Tabelle mit dem Ergebnis dieser Abfrage zu aktualisieren, können Sie wie folgt vorgehen:

update Products 
left join Filters 
on Products.name LIKE CONCAT('%',Filters.filter,'%') 
left join Categories 
on Categories.name = Filters.category_name 
set Products.category_name = Filters.category_name, 
    Products.category_id = Categories.id; 

Click here for Working Demo

Hoffe, es hilft!

+0

Schau dir das Ergebnis an, das du in der letzten Tabelle hast: Tomatensuppe bekommt Filter "Tomaten" und Kategorie "Zutaten". Das ist mein Problem: Ich brauche es, um die erste Zeile in "Filter" -Tabelle übereinstimmen. Für "Tomatensuppe" wird es "Suppe", nicht "Tomate" sein. Gleiches gilt für "Pilzsuppe" - Suppe sollte eine höhere Priorität als "Pilz" oder "Tomate" haben, weil sie in der Tabelle "Filter" an erster Stelle steht. – Trost

+0

Ok. Ich denke, ich habe die Lösung. Wird nach einer Weile aktualisiert, während ich rn unterwegs bin. –

+1

UPD: Der vorherige Kommentar bezieht sich auf die Auswahl, die Sie in den Zeilen 7-12 geschrieben haben. Die Aktualisierungsabfrage scheint jedoch so zu funktionieren, wie ich sie brauche. Ich schätze, ich habe nur ein paar Stunden verschwendet, weil ich vor dem zweiten Beitritt nicht "links" geschrieben habe. Ich nahm auch an, dass "join" standardmäßig aus irgendeinem Grund "nach links geht". Danke für die Hilfe! Ich fing an, in die falsche Richtung zu graben und brauchte ein frisches Aussehen. Und ja, ich versuche mein Bestes, um die Problembeispiele so zugänglich wie möglich zu machen, damit die Leute einfach Zeit haben, mir zu helfen. – Trost