Jump to content
TzingTzongPing

Ajutor PHP-SQL

Recommended Posts

Posted (edited)

Salut, incerc sa fac un filter pentru produse in laravel, si m-am blocat la partea cu sql.

 

 

Tabel e_products
`id` int(11) NOT NULL auto_increment,
`title` varchar(255) NOT NULL
..

 

Tabel e_products_attributes

`id` int(11) NOT NULL auto_increment,
`product_id` int(11) NOT NULL
`variable` int(11) NOT NULL

 

Tabel e_attributes

`id` int(11) NOT NULL auto_increment,
`variable` int(11) NOT NULL
`label` varchar(255) NOT NULL

 

PHP

 

$variables = array(41, 2, 4, 6);
$rr = count($variables);
$list = implode(',', $variables);
	
$objects = DB::select('SELECT
    o.id,
	o.title,
	o.slug,
	o.images_host,
	o.regular_price
FROM
    e_products o INNER JOIN e_products_attributes oa ON o.id = oa.product_id AND oa.variable IN ('.$list.')
GROUP BY o.id
HAVING COUNT(oa.variable) >= '.$rr);

 

variable 41 = Samsung

variable 2 = Philips

variable 4 = 22 inch

variable 6 = 24 inch

 

Problema este in felul urmator: Daca in $list se afla variable 41,6 rezultatele sunt corecte, dar daca selectez doar 41,2 imi da rezultate 0, cea ce nu pot sa inteleg este faptul ca fiecare attribute are un id dar  filtreaza doar brand si inch.

 

e_products_attributes arata cam asa:

id product_id  variable
1  400         41
2  400         6
3  450         41
4  451         2

 

Deci daca selectez variable 41 trebuie sa afiseze toate produsele cu acest attribute, dar daca selectez 41,6 trebuie sa afiseze doar product_id 400

 

Stie cineva unde gresesc ?

Multumesc

Edited by TzingTzongPing
Posted (edited)

Daca nu folosesti nimic din tabelele din join de ce faci join?

Fa select pe products si WHERE id IN (SELECT product_id FROM product_attributes WHERE variable IN (" . $list . ")

Foloseste HeidiSQL pentru managementul bazei de date si construirea query-urilor, apoi le treci in PHP.

Edited by Wav3
Posted (edited)

Am inteles

 

Am facut asa numai ca imi da o eroare

 

[2019-01-29 16:54:31] production.ERROR: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1 
(SQL: SELECT * FROM e_products WHERE id IN (SELECT product_id FROM e_product_attributes WHERE variable IN (306,163,259))

 

$objects = DB::select('SELECT 
	 * 
	 FROM 
	 e_products 
	 WHERE id IN 
	 (SELECT product_id 
	 FROM e_products_attributes 
	 WHERE variable IN 
	 ('.$list.'))
     ');

 

Edited by TzingTzongPing
Posted

Ai avut perfecta dreptate, query functioneaza doar ca afiseaza toate produsele care au macar 1 attribute din WHERE variable IN, eu am nevoie daca selectez "samsung (attribute 41)", philips (attribute 2), si 22 inch (attribute 4) sa afiseze doar samsung si philips care au 22 inch, acuma din pacate afiseaza toate produsele samsung, philips si nu filtreaza pe 22 inch.

 

Am incercat asta https://stackoverflow.com/a/15900486 dar afiseaza doar samsung si 22 inch daca selectez si philips numai afiseaza nimic.

 

Am incercat si asta https://stackoverflow.com/a/19333809 dar imi afiseaza doar 1 singur produs daca selectez samsung si philips, iar daca selectez toate 3 iar nu afiseaza nimic.

Posted

Pai si de unde vrei sa stie MySQL ca o variabila reprezinta brand-ul iar alta diagonala? Este prost facuta structura tabelului. Adauga un variable_type in tabelul de variabile si stabileste care sunt brand, diagonala, etc. Nu le poti pune la gramada si sa te astepti sa se faca diferenta prin minune.

 

Posted (edited)

Am facut si asta, am si tabel attributes si attribute_id in variables exact ca aici https://stackoverflow.com/q/19333652, dar nu inteleg diferenta intre variable_type si doar variable

 

SELECT `p`.`id`, `p`.`title`
FROM   `e_products` `p`
WHERE   `p`.`id` IN (SELECT     `ae`.`product_id`
                     FROM       `e_products_attributes` `ae`
                     INNER JOIN `e_attributes` `a` ON `ae`.`attribute_id`=`a`.`id`
                     INNER JOIN `e_attributes_options` `av` ON `ae`.`variables`=`av`.`value`
                     WHERE       ((`a`.`code`='brands' AND `av`.`value`='306') OR
                                  (`a`.`code`='tvs_size' AND `av`.`value`='411'))
                     HAVING COUNT(*) >= 2
                    );

 Dar imi afiseaza doar 1 singur produs in cazul de fata doar primul produs cu brand attribute 306

Edited by TzingTzongPing
Posted (edited)

Mda, invata bazele si dupaia baga-te la modificat script-uri.

De unde este copiat acel query?

1. Cand ai multe inregistrari in tabele nu faci join. Incerci pe cat posibil subquery, insa sunt si (multe) exceptii. 2 join-uri in subquery + having este moartea pasiunii;

2. Incearca sa folosesti direct numele tabelului atunci cand nu il folosesti de 2 sau mai multe ori in acelasi query. Este greu sa citesti un query cu atatea aliasuri;

2.2. Daca tot esti nevoit sa prefixezi, foloseste si AS intre numele tabelului si alias;

3. Renunta la tilde si la a prefixa coloanele cu tabelul atunci cand nu e nevoie.

 

Pune structura tabelelor ca sa intelegem clar cum ai tabelele facute. Oricum, imi par gresite. Nu vad rostul sa ai 7 tabele, cate unul pentru fiecare coloana.

Edited by Wav3
Posted

Daca folosesti Laravel si faci query-uri cu DB, din punctul meu de vedere, cred ca ratezi scopul framework-ului.

Ar trebui sa te uiti la Collections sau pachete cum e Nova. Este posibil ca la inceput sa-ti fie mai greu sa le folosesti dar dupa ce le prinzi miscarea iti vor fi de mare ajutor.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...