2012-04-02 45 views
5

Mam system zbudowany na relacyjnej bazie danych MySQL, która pozwala ludziom przechowywać szczegóły "leadów". Ponadto, ludzie mogą tworzyć własne kolumny, w których przechowują dane, a następnie dodając nowe konta mogą dodawać dane pod nimi. Struktura tabeli wygląda następująco:Jak odzyskać atrybuty "dynamiczne" przechowywane w wielu wierszach jako normalne rekordy?

PROWADZI - ID, e-mail, USER_ID

atrybuty - id, attr_name, user_id

ATTR_VALUES - lead_id, attr_id, wartość: identyfikator_użytkownika

Oczywiście w tych tabelach "user_id" odnosi się do tabeli "Users", która zawiera tylko osoby, które mogą zalogować się do systemu.

Piszę funkcję do wyprowadzania szczegółów ołowiu, a obecnie właśnie przechodzę przez podstawowe szczegóły ołowiu jako zapytanie, a następnie przeciągając przez każdą wartość atrybutu związaną z tym potencjalnym klientem (dołączając do tabeli atrybutów, aby uzyskać nazwę) i następnie dołączanie do tablic w PHP. Jest to trochę nieporządne i zastanawiałem się, czy istnieje sposób, aby to zrobić w jednym zapytaniu SQL. Czytałem trochę o czymś zwanym "stołem przestawnym", ale staram się zrozumieć, jak to działa.

Każda pomoc zostanie bardzo doceniona. Dzięki!

+0

MySql nie obsługuje poleceń Pivot. Eh, to nic nie kosztuje. – McGarnagle

+0

@dbase (microsoft?) Człowiek: nie * "Eh, to nic nie kosztuje" *, ale * "Eh, to baza danych" * (w przeciwieństwie do ...). Polecenia przestawne nie należą do bazy danych, ale do poziomu prezentacji. – TMS

+0

Dobre pytanie, chociaż tytuł wprowadzał w błąd - jest możliwe w pojedynczej kwerendzie z łatwością, wystarczy normalnie dołączyć do wszystkich tabel - ale to nie jest to, czego prawdopodobnie chcesz. Edytowano tytuł. – TMS

Odpowiedz

0

Chciałbym rzucić okiem na to link. Że wyjaśnić podstawową z czopem:

„tabeli przestawnej” lub „Raport krzyżowa” SQL Funkcje charakterystyczne: Czy go bez „jeśli”, „przypadek”, czy „GROUP_CONCAT”. Tak, jest użycie dla tego ... "jeśli" instrukcje czasami powodują problemy, gdy są używane w kombinacji . Prostym sekretem, a także dlatego, że działają prawie w każdej bazie danych, są następujące funkcje: sign (x) zwraca -1,0, +1 dla wartości x < 0, x = 0, x> 0 odpowiednio abs (sign (x)) zwraca 0 jeśli x = 0 else, 1 jeśli x> 0 lub x < 0 1-abs (znak (x)) uzupełnienie powyższego , ponieważ zwraca 1 tylko wtedy, gdy x = 0

To również wyjaśnić prostszy sposób przechylania egzaminów. Może to może rzucić trochę światła na to?

1

Można wykonać obrót w jednym zapytaniu jak następuje:

select l.id lead_id, 
     l.email, 
     group_concat(distinct case when a.attr_name = 'Home Phone' then v.value end) HomePhone, 
     ... 
from leads l 
left join attr_values v on l.id = v.lead_id 
left join attributes a on v.attr_id = a.id 
group by l.id 

Trzeba będzie zawierać osobny group_concat pochodzące z A pole dla każdego atrybutu, który chcesz wyświetlić.

0

To, czego prawdopodobnie oczekujesz od mysql, to utworzenie wartości sql (attr_name w twoim przypadku) w kolumnie. Zasada ta nazywa się pivot table (czasami są to również tabele krzyżowe lub zapytania krzyżowe) i nie jest obsługiwana przez mysql. Nie dlatego, że mysql jest niewystarczający, ale dlatego, że operacja przestawna nie jest operacją bazy danych - wynikiem nie jest zwykła tabela bazy danych i nie jest ona przeznaczona do dalszych operacji na bazie danych.Jedynym celem operacji obrotu jest prezentacja - dlatego należy do warstwy prezentacji, a nie do bazy danych.

W ten sposób każde rozwiązanie prób uzyskania tabeli przestawnej z mysql zawsze będzie odstraszać. Co mogę polecić to, aby uzyskać dane z bazy danych w normalnym formacie, po prostu robi coś takiego:

select * 
from attr_values join attributes using on attr_id = attributes.id 
    join leads on leads.id = lead_id 

a następnie przekształcić wyjście bazy danych w języku prezentacji (PHP, JSP, Python lub cokolwiek używasz).

0

Będę ostrożnie zakładać, że pivot osiągnie cel upraszczania. Pivot będzie działał tylko wtedy, gdy nazwa attr_name będzie spójna. Ponieważ przywiązałeś do niego identyfikator użytkownika, zakładam, że tak nie jest. Ponadto będziesz mieć wiele wartości dla jednego attr_name. Obawiam się, że tabela przestawna nie przyniesie oczekiwanego wyniku.

Proponuję zachować oddzielne tabele transakcyjne i raporty. Mieć procedurę ETL, która oczyści (tzn. Sprawi, że attr_name i attr_value) będą spójne dzięki translacji. Dzięki temu Twoje raporty będą bardziej znaczące.

Podsumowując, do natychmiastowego wyświetlenia użytkownikowi końcowemu, PHP jest najlepszym rozwiązaniem. Aby wygenerować raport, najpierw przekształć wartość EAV w wiersz/kolumnę, zanim podejmiesz próbę zgłoszenia.