PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Spalte mehrere Kriterien



wackeldackel
02-06-2005, 06:27
Guten Morgen,

ich bräuchte ne kurze Hilfe zu folgendem Problem:

ich habe eine tabelle, in der merkmale zu einem artikel vorhanden sind.

Tabelle: Artikelmerkmal

id - artikel_id - merkmal
1 --- 1 --- 3
2 --- 1 --- 9
3 --- 1 --- 7
4 --- 2 --- 3
5 --- 2 --- 5
6 --- 3 --- 3
7 --- 3 --- 7
8 --- 3 --- 8


jetzt müsste ich aus einem formular, in dem nicht immer alle kriterien abgefragt werden, ne abfrage basteln, die mir nur die artikel_id sucht, die alle kriterien erfüllt

sowas wie:

select from Artikelmerkmal where merkmal = 3 and merkmal = 7 ...

das funktioniert natürlich nicht.

wenn ich das mache:

select artikel_id from Artikelmerkmal where merkmal in ( 3, 7 )

dann bekomme ich

artikel_id
1
1
2
3
3

wobei die artikel_id 2nur ein Kriterium erfüllt und somit eigentlich nicht zutrifft.

Kann man das in einer Abfrage machen, oder muss daraus erst eine Kreuztabelle generieren und dann die Abfrage machen ???

wackeldackel
02-06-2005, 06:47
Schreiben stimuliert scheinbar das Gehirn.

Ich habe es jetzt so gemacht, dass ich in der Abfrage noch die Summe aus den Artikelmerkmalen bilde. Dann vergleich ich, ob die Summe der Artikelmerkmale mit der Summe der angeforderten Kriterien entspricht.

Soweit meine erste Lösung. Für Anregungen bin ich immer offen.

Gruss Wackeldackel

elrond
02-06-2005, 07:32
das funktioniert indem du die selbe tabelle einfach in eine Abfrage einbindest:

select k1.* from Artikelmerkmal k1, Artikelmerkmal k2 , Artikelmerkmal k3
where k1.artikelid=k2.artikelid
and k1.merkmal=9
and k2.merkmal =3
and k1.artikelid=k3.artikelid
and k3.merkmal =7

Damit wirdt die die Datensätze erhalten, deren merkmal=9 und die mit den anderen beiden Merkmalen vorhanden sind.

Alternativ geht die Verwendung von exist(), aber da ich auf mysql tippe wird das wohl nichts...

wackeldackel
02-06-2005, 07:54
Hallo Elrond,

danke für die Antwort, so habe ich das noch gar nicht gesehen.
Ist tausendmal einfacher, als was ich da hätte machen wollen.
Voll krass, werde ich gleich testen.

P.S. Nix mysql korrekte Postgres :)

Gruss Wackeldackel

mwanaheri
02-06-2005, 08:33
Das konnte ich auch gerade gebrauchen und habe daher noch mal rumprobiert (postgresql). Es geht auch so:


select * from b
where artikel in
(select artikel from b where artikel in
(select artikel from b where merk = 6)
and merk = 5)
and merk = 3;

Ist natürlich lästig zu machen, wenn man nicht weiß, wie viele Angaben gemacht wurden.

sticky bit
02-06-2005, 09:31
Wenn Du nur die IDs brauchst tut vielleicht auch ein DISTINCT?

SELECT DISTINCT artikel_id FROM artikelmerkmal WHERE merkmal IN ( 3, 7 );

elrond
02-06-2005, 10:08
in der postgres würde ich es mit exists/subselects machen:

select k1.* from Artikelmerkmal k1
where k1.merkmal=9
and exists(select * from Artikelmerkmal k2 where k1.artikelid=k2.artikelid and k2.merkmal =3)
and exists(select * from Artikelmerkmal k3 where k1.artikelid=k3.artikelid and k2.merkmal =7)

sieht besser aus ;) , und ist auch bei großen Datenmengen schnell (ordentliche indizierung vorausgesetzt)

elrond
02-06-2005, 10:09
Wenn Du nur die IDs brauchst tut vielleicht auch ein DISTINCT?

SELECT DISTINCT artikel_id FROM artikelmerkmal WHERE merkmal IN ( 3, 7 );

das läüft auf ein ODER hinaus gefragt war UND... :cool:

mwanaheri
02-06-2005, 10:42
Wenn schon, dann sollte man den besten Treffer rauspicken:

select * from
(select sum(artikel),artikel from b where merk in (3,4,5) group by artikel) as c
order by sum desc
limit 1;

So kriegt man Trefferzahl und Artikel eines Artikels, der die meisten Anforderungen erfüllt. Es ist aber keineswegs sicher, dass er alle Anforderungen erfüllt und dass er der einzige ist.

@Elrond: stimmt, die exists-Lösung sieht besser aus. Bei den 10 Einträgen in meiner Test-Tabelle wage ich nicht mal an die Geschwindigkeit bei ernsthaften Tabellen zu denken ;-)

sticky bit
02-06-2005, 13:24
das läüft auf ein ODER hinaus gefragt war UND... :cool:Yo, sorry nicht richtig gelesen / verstanden... hey es ist Donnerstag da bin ich von natur aus müde und wirr im Kopf... ;)

wackeldackel
03-06-2005, 07:29
Guten Morgen miteinander,

Wow. Soviele Antworten. Danke.

Denke die Sache von elrond würde sich am einfachsten machen lassen.

Die Sache ist ja die:

Das Menu besteht aus einer Reihe von Dropdowns. Die Anzahl der Dropdowns wird durch eine Tabelle gesteuert. Der Inhalt der einzelnen Dropdowns stammen dann wieder aus einer zweiten Tabelle, die mit dieser verknüpft ist. Somit habe ich keine Probleme damit zusätzliche Auswahlkriterien einzufügen.

Allerdings muss ich mir halt was basteln, um dann die Abfrage hinzubekommen. Die Daten kommen als Array und mit dem muss ich dann diese Abfrage von elrond zusammenstopseln.
Aber das wird schon :)

Gruss Wackeldackel

wackeldackel
14-06-2005, 11:55
Hallo Leute,

danke noch mal für die Tipps.
Habe es jetzt ganz anders gemacht.

Die Werte aus dem Menu kommen per Array rüber. Falls etwas ausgewählt wurde, dann eben der Wert (eindeutiger Wert), oder halt eine "0".
Die Werte packe ich per implode(',', array) zusammen


$string_array=implode(',' ,$HTTP_POST_VARS['txtMerkmal']);
Ergibt sowas wie 0,9,3,0,0,0,0,8

Dann mache ich noch die Summe daraus:

$summe_array=array_sum($HTTP_POST_VARS['txtMerkmal']);
Ergibt dann halt 20

Das übergebe ich an die Abfrage und schon habe ich alle eindeutigen Datensätze.

$SQL_mel = "SELECT fif_fvw_key, sum(fif_fom_merkmal) AS summe FROM formeninfo WHERE fif_fom_merkmal in (" . $string_array . ") group by 1 having sum(fif_fom_merkmal) = " . $summe_array . " order by 1 ";

Damit habe ich keine Probleme damit wieviele Dropdowns ich auswerten muss und was genau rüberkommt. :D

Gruss Wackeldackel

elrond
14-06-2005, 12:02
Dir ist aber schon Folgendes klar:

8+9+3 = 5+7+8 ..... = 20

Eindeutig ist mit der Zahl 20 nichts!

wackeldackel
14-06-2005, 12:15
Hallo Elrond,

klar ist mir das klar.

AAABER !!!

durch "where fif_fom_merkmal in ( 8, 9, 3)" habe ich ja nur diese Zahlen.
Deshalb ist das schon sehr eindeutig :)
Allerdings würde ich hier auch alle Zeilen bekommen, in denen auch nur die 8 oder 9 oder 8 und 9 wären. Das verhindere ich durch having.

Gruss Wackeldackel