2010-01-22 12 views
7

I asked a question yesterday o używaniu MySQL do porównania wyników z ankietą.Jak wybrać wiele pól w tym samym rzędzie? (MySQL)

Moje pytanie brzmi: gdybym miał tabelę pytań ankietowych, tabelę pytań do ankiety i tabelę odpowiedzi użytkowników na te pytania ankietowe, w jaki sposób wybrałbym pytanie ankiety wraz z wszystkimi wyborami do tej ankiety w ramach tego samego zapytania?

pytania Tabela

question_id (int) 
question (text) 

Choices Tabela

choice_id (int) 
question_id (int) 
choice_text (varchar) 

odpowiedzi Tabela

answer_id (int) 
question_id (int) 
choice_id (int) 

Co SELECT należy zrobić, aby dostać się pytanie ankiety wraz ze wszystkimi wyborów dla tego badania (znana lub nieznana ilość) wszystko w tym samym zapytaniu? (Jeśli to możliwe, zrób również matematykę, znalezioną w moim drugim pytaniu, w tym samym zapytaniu)

Nie jestem tak zaawansowany w MySQL.

Dzięki

EDIT: Niestety Chodziło mi o to, próbuję dostać SELECT, aby wybrać pytanie, a wszystkie wybory odpowiada na to pytanie, w jednym rzędzie.

Jeśli zrobię coś podobnego

SELECT question_id, question, choice_id, choice_text FROM questions LEFT JOIN choices USING(question_id) 

uzyskać wiele wierszy, po jednym dla każdej choice_id.

Wyniki powinny być coś

question  choice_1 choice_2 choice_3 
A or B or C  A   B  C 

Część matematyka jest liczenie się wyniki badania, i tak, choice_id jest PK, czy to pomaga.

+0

Czy chcesz po prostu chocies, a także hrabiów? Jakie jest twoje "inne pytanie" i jaką "matematykę" chcesz robić? –

+0

Nie szukasz żadnych informacji dotyczących prawidłowej odpowiedzi? Tylko pytania/możliwości wyboru? –

+0

@Evan: to ankieta, a nie test - nie ma poprawnej odpowiedzi. – Martha

Odpowiedz

4

Aby uzyskać pytań i wyborów dla każdego pytania:

SELECT question, choice_text 
FROM questions 
JOIN choices 
ON questions.question_id = choices.question_id 

dodawania lewo przed DOŁĄCZ jeśli chcemy także pytania, które nie mają wyboru.

Aby uzyskać liczniki dla każdej odpowiedzi można to zrobić:

SELECT question, choice_text, COUNT(answers.choice_id) 
FROM questions 
JOIN choices 
    ON questions.question_id = choices.question_id 
LEFT JOIN answers 
    ON questions.question_id = answers.question_id 
    AND choices.choice_id = answers.choice_id 
GROUP BY questions.question_id, choices.choice_id 
ORDER BY questions.question_id, choices.choice_id 

Aby uzyskać liczbę osób wybranych każdą odpowiedź w procentach (za pytanie) należy stosować następujące zapytanie:

SELECT question, choice_text, COUNT(answers.choice_id) * 100/questiontotal 
FROM questions 
JOIN (
     SELECT questions.question_id, COUNT(answers.choice_id) AS questiontotal 
     FROM questions 
     LEFT JOIN answers ON questions.question_id = answers.question_id 
     GROUP BY questions.question_id 
    ) AS answercounts 
    ON questions.question_id = answercounts.question_id 
JOIN choices ON questions.question_id = choices.question_id 
LEFT JOIN answers 
    ON questions.question_id = answers.question_id 
    AND choices.choice_id = answers.choice_id 
GROUP BY questions.question_id, choices.choice_id 
ORDER BY questions.question_id, choices.choice_id; 

Oto testdata użyłem:

CREATE TABLE questions (question_id int, question nvarchar(100)); 
INSERT INTO questions (question_id, question) VALUES 
(1, 'Foo?'), 
(2, 'Bar?'); 

CREATE TABLE choices (choice_id int, question_id int, choice_text nvarchar(100)); 
INSERT INTO choices (choice_id, question_id, choice_text) VALUES 
(1, 1, 'Foo1'), 
(2, 1, 'Foo2'), 
(3, 1, 'Foo3'), 
(4, 2, 'Bar1'), 
(5, 2, 'Bar2'); 

CREATE TABLE answers (answer_id int, question_id int, choice_id int); 
INSERT INTO answers (answer_id, question_id, choice_id) VALUES 
(1, 1, 1), 
(2, 1, 1), 
(3, 1, 3), 
(4, 2, 4), 
(4, 2, 5); 

a wyjście otrzymuję z ostatniego zapytania na temat tych danych:

'Foo?', 'Foo1', 66.6667 
'Foo?', 'Foo2', 0.0000 
'Foo?', 'Foo3', 33.3333 
'Bar?', 'Bar1', 50.0000 
'Bar?', 'Bar2', 50.0000 

W aktualizacji swojego pytania mówisz, że chcesz zwrócić wszystkie wartości dla jednego pytania w jednym wierszu.Polecam, abyś zrobił , a nie spróbuj to zrobić, a zamiast tego użyj metody, którą ci podałem powyżej. Jeśli chcesz przedstawić dane w jednym wierszu swojemu użytkownikowi końcowemu, możesz to zrobić za pomocą PHP.

0
SELECT questions.question_id, questions.question, choices.choice_id, choices.question_id 
FROM questions, choices 
WHERE questions.question_id = choices.question_id 
AND questions.question_id = "Something" 

Powinien działać, chyba.

2

Należy zauważyć, że tabela odpowiedzi prawdopodobnie nie wymaga kolumny Question ID.

Spowoduje to wyświetlenie tekstu pytania, tekstu wyboru i liczby odpowiedzi dla każdego wyboru.

SELECT Questions.question, Choices.choice_text, Count(Answers.*) AS N 
FROM Questions INNER JOIN Choices ON Questions.question_id = Choices.question_id 
    LEFT JOIN Answers ON Choices.choice_id = Answers.choice_id 
GROUP BY Questions.question_id, Choices.choice_id 

Edit: chyba że jesteś bardzo dobry w SQL, to chyba najlepiej zapomnieć o „wszystkich jednym rzędzie” części - o ile liczba wyborów na pytanie nie tylko znane, ale na stałym poziomie, a nawet w tym przypadku nie jest to łatwe. To naprawdę problem z wyświetlaniem, więc radzę sobie z nim, gdy wyświetlasz wyniki.

+0

+1 za poradę dotyczącą części "wszystkie jeden wiersz". –

+0

I chciałbym dać jeszcze +1 za wskazanie niepotrzebnej kolumny QuestionID. –

+0

Niestety, twoje zapytanie nie działa dla mnie. Otrzymuję komunikat "Masz błąd w składni SQL; sprawdź instrukcję, która odpowiada twojej wersji serwera MySQL dla właściwej składni do użycia w pobliżu "*) AS N Z pytaniami WEJŚCIE WEWNĘTRZNE Wybory Wybory w Question.question_id = Choices.q 'w linii 1 –

3

Proponuję odpowiedź Marka Byersa, choć teoretycznie, jeśli potrzebujesz ich "wszystko w jednym rzędzie", tylko do celów przeglądania, ale nie jako część rutynowej czynności PHP.

SELECT question, GROUP_CONCAT(choice_text) as choice_texts 
FROM questions 
JOIN choices 
ON questions.question_id = choices.question_id 
GROUP BY question; 

Wyjście byłoby

'Foo?', 'Foo1,Foo2,Foo3' 
'Bar?', 'Bar1,Bar2' 

Uwaga „foo1, foo2, foo3” zostaną zwrócone jako jedna kolumna nie trzech kolumn, a GROUP_CONCAT ma maksymalnie 1024 znaków w swoim wyjściu domyślnie choć można go zwiększyć. Nie jest to zalecane, jeśli wyniki mogą być duże.

Powiązane problemy