Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Zapytanie CrossTab (Pivot)
Forum PHP.pl > Forum > Bazy danych > MySQL
Adi32
(polskie znaki mi wywalilo na ubuntu)

Czesc,

Mam problem z zapytaniem typu crosstab (to w sumie 5 zapytan);

Na wstepie napisze ze te rozwiazania u mnie nie zdaja egzaminu:
http://stackoverflow.com/questions/1238277...-crosstab-query
http://stackoverflow.com/questions/1599709...b-view-in-mysql

Dostaje syntax "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FROM csre_profile LEFT JOIN csre_profile_data ON csre_profile.csre_profile_id"
ktory nie ma sensu.

Testowe zapytanie ktore proboje wywolac wyglada tak: (jest poprzeinaczane, robilem wszystko zeby najpierw SQL cokolwiek mi zwrocil)

  1. SET @sql = NULL;
  2.  
  3. SELECT
  4. GROUP_CONCAT(DISTINCT
  5. CONCAT(
  6. ' GROUP_CONCAT(CASE question_normalized when ', question_normalized , ' then question_value else NULL END) AS `',
  7. question_normalized, '`'
  8. )
  9. ) INTO @sql
  10. FROM csre_profile LEFT JOIN csre_profile_data ON csre_profile.csre_profile_id = csre_profile_data.csre_profile_fk
  11. LEFT JOIN csre_question ON csre_question_id=csre_profile_data.csre_question_fk;
  12.  
  13. SET @sql =
  14. CONCAT('SELECT csre_profile_id, name, email, ', @sql, '
  15. FROM csre_profile LEFT JOIN csre_profile_data ON csre_profile.csre_profile_id = csre_profile_data.csre_profile_fk
  16. GROUP BY csre_profile_id LEFT JOIN csre_question ON csre_question_id=csre_profile_data.csre_question_fk');
  17.  
  18. PREPARE stmt FROM @sql;
  19. EXECUTE stmt;
  20. DEALLOCATE PREPARE stmt;


Dane:
3 tabele.

csre_profile: csre_profile_id | name | surname .... === tu niejasnosci nie ma
csre_profile_data: csre_profile_data_id | csre_profile_fk | question_fk | question_value === csre_profile_fk to klucz z tabeli glownej, question_fk to id z tabeli ze zbiorem wartosci (ulica, plec itp), question_value to odpowiedz na pytanie (np: kobieta)
csre_question: csre_questio_id | question_name | question_normalized === question_normalized to pytanie znormalizowane bez pl znakow i spacji.

Chcialbym uzyskac swoim zapytaniem taki efekt:

id | name | gender | avatar .....
1 Zoska Kobieta http://costam

Gdzie kolumny gender i avatar sa wartosciami z tabeli csre_profile_data.

nospor
A patrzyles jak wyglada zbudowane do konca @sql ?
Adi32
PS. @nospor Daj znac jak nie bedzie Ci sie chcialo nad tym zastanowic. Jak Ty tego nie napiszesz to nikt inny pewnie tez...

O wasnie pisaem do Ciebie.
Zaraz rozkminie jak sie wyswietlalo zawartosc zmiennych w sql.
nospor
Nie traktuj mnie prosze jak wyrocznie.... jest cala masa ludzi na forum, co niedosc ze moze im sie bardziej chciec ode mnie, to znają lepiej bazy ode mnie. I takim postępowaniem tyko ich obrażasz a co za tym idzie szkodzisz sam sobie, bo możesz ich zniechęcić do odpowiedzi.
Adi32
Nie chodzilo mi tylko o umiejetnosci ale bardziej o checi smile.gif

Zmienna zawiera uciete zapytanie:

  1. GROUP_CONCAT(CASE question_normalized when pr_about then question_value else NULL END) AS `pr_about`,
  2. GROUP_CONCAT(CASE question_normalized when pr_gender then question_value else NULL END) AS `pr_gender`,
  3. GROUP_CONCAT(CASE question_normalized when pr_brand then question_value else NULL END) AS `pr_brand`,
  4. GROUP_CONCAT(CASE question_normalized when pr_regulations_data then question_value else NULL END) AS `pr_regulations_data`,
  5. GROUP_CONCAT(CASE question_normalized when pr_personal_data then question_value else NULL END) AS `pr_personal_data`,
  6. GROUP_CONCAT(CASE question_normalized when pr_marketing_data then question_value else NULL END) AS `pr_marketing_data`,
  7. GROUP_CONCAT(CASE question_normalized when pr_company then question_value else NULL END) AS `pr_company`,
  8. GROUP_CONCAT(CASE question_normalized when pr_title then question_value else NULL END) AS `pr_title`,
  9. GROUP_CONCAT(CASE question_normalized when pr_position then question_value else NULL END) AS `pr_position`,
  10. GROUP_CONCAT(CASE question_normalized
Crozin
Próbujesz porównać kolumnę question_normalized z nieistniejącymi kolumnami pr_xxx, a powinieneś z tekstem:
  1. ...CASE question_normalized when 'pr_company' then question_value...
mmmmmmm
GROUP_CONCAT ma (domyślnie) ograniczenie do 1024 znaków. Trzeba o tym pamiętać...
nospor
Swoją drogą czemu robisz to przez jedno zapytanie? Pobierz dane normalnie w mysql, a potem pogrupuj w php i wyswietlaj jak ci pasuje. Bedzie znacznie lepiej

http://nospor.pl/grupowanie-wynikow.html
U mnie grupowanie posluzylo do wyswietlenia danych w formie list, ale nic nie stoi na przeszkodzie bys u siebie na podstawie tych danych zbudowal to co chcesz
Adi32
Dzieki Panowie.

Zaskoczylo i dziala pieknie. Jak beda problemy z indeksowaniem to zrobie jak mowi Nospor.

Zapytanie koncowe wyglada tak:

  1. SET @sql = NULL;
  2.  
  3. SET SESSION group_concat_max_len = 1000000;
  4.  
  5. SELECT
  6. GROUP_CONCAT(DISTINCT
  7. CONCAT(
  8. ' (CASE question_normalized when "', question_normalized , '" then question_value else NULL END) AS `',
  9. question_normalized, '`'
  10. )
  11. ) INTO @sql
  12. FROM csre_profile LEFT JOIN csre_profile_data ON csre_profile.csre_profile_id = csre_profile_data.csre_profile_fk
  13. LEFT JOIN csre_question ON csre_question_id=csre_profile_data.csre_question_fk;
  14.  
  15. SET @sql =
  16. CONCAT('SELECT csre_profile_id, name, email, ', @sql, '
  17. FROM csre_profile LEFT JOIN csre_profile_data ON csre_profile.csre_profile_id = csre_profile_data.csre_profile_fk
  18. LEFT JOIN csre_question ON csre_question_id=csre_profile_data.csre_question_fk');
  19.  
  20. PREPARE stmt FROM @sql;
  21. EXECUTE stmt;
  22. DEALLOCATE PREPARE stmt;


Jak to jest z poziomu PHP to zapytanie nie dziala?

  1. An exception occurred while executing 'PREPARE stmt FROM @sql':
  2.  
  3. SQLSTATE[42000]: Syntax error OR access violation: 1064 You have an error IN your SQL syntax; CHECK the manual that corresponds TO your MySQL server version FOR the RIGHT syntax TO USE near 'SELECT
  4. csre_profile_id, name, email, GROUP_CONCAT(CASE question_normalized wh' at line 3


  1. $em->getConnection()->beginTransaction();
  2.  
  3. $query = $em->getConnection()->query("SET @sql = NULL");
  4. $query->execute();
  5.  
  6. $query = $em->getConnection()->query("SET SESSION group_concat_max_len = 1000000");
  7. $query->execute();
  8.  
  9. $query = $em->getConnection()->query("
  10. SELECT
  11. GROUP_CONCAT(DISTINCT
  12. CONCAT(
  13. 'GROUP_CONCAT(CASE question_normalized when \', question_normalized , \' then question_value else NULL END) AS ',
  14. question_normalized
  15. )
  16. ) INTO @sql
  17. FROM csre_profile_data LEFT JOIN csre_profile ON csre_profile.csre_profile_id = csre_profile_data.csre_profile_fk
  18. LEFT JOIN csre_question ON csre_question_id=csre_profile_data.csre_question_fk
  19. ");
  20. $query->execute();
  21.  
  22. $query = $em->getConnection()->query("
  23. SET @sql = CONCAT('
  24. SELECT
  25. csre_profile_id, name, email, ', @sql, '
  26. FROM
  27. csre_profile LEFT JOIN csre_profile_data ON csre_profile.csre_profile_id = csre_profile_data.csre_profile_fk
  28. LEFT JOIN csre_question ON csre_question_id=csre_profile_data.csre_question_fk
  29. GROUP BY csre_profile_id ORDER BY csre_profile_id DESC')
  30. ");
  31. $query->execute();
  32.  
  33. $query = $em->getConnection()->query("PREPARE stmt FROM @sql");
  34. $query->execute();
  35.  
  36. $query = $em->getConnection()->query("EXECUTE stmt");
  37. $query->execute();
  38.  
  39. $query = $em->getConnection()->query("DEALLOCATE PREPARE stmt");
  40. $query->execute();
  41.  
  42. $em->commit();
  43. die(print_r($query->fetchAll()));
Crozin
Ale po co chcesz samo budowanie zapytania robić po stronie SQL-a. Przecież Ty teraz "ręcznie" symulujesz działanie metod Connection::prepare() czy Statement::execute().
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.