2016-05-20 1 views
-1

У меня возникло сомнение в запросе SELECT.Разбить результат SQL на поля и повернуть их в столбцах

В моем проекте у меня есть основная таблица для пользователей и я создал еще несколько таблиц, чтобы разделить содержание, что-то вроде этого:

tblUser UID uname udateofbirth uadress

tblPhoneNumber PID UID PTYPE pnumber

tblPhoneRelation UID pid

Мне нужно ВЫБРАТЬ поля из таблицы пользователей с результатами телефонной таблицы, но проблема в том, что мне нужно разделить телефоны на разные поля, и мой поиск номера телефона может вернуть от 0 до 4 результатов для каждого пользователя.

То, что я получил, это похоже на это и дает мне результат сотового телефона (определенный в PTYPE как 1 на мобильный телефон, 2 для домашнего телефона, 3 для коммерческого телефона и 4 для сообщения):

SELECT u.uname AS Name, u.udateofbirth AS 'Date of B.', p.pnumber AS 'Cell phone' FROM tblUser AS u JOIN phonerelation ON u.uid = phonerelation.uid JOIN tblPhoneNumber AS p WHERE p.pid = 1 AND p.pid = phonerelation.pid; 

И мой результат

Имя | Дата Б. | Сотовый телефон

Но мне нужно увеличить до:

Имя | Дата Б. | Сотовый телефон | Домашний телефон | Торговый телефон | Телефон сообщений

Sugestions?

+0

вы можете разместить некоторые таблицы/данные на http://sqlfiddle.com/ –

ответ

0

Вы можете использовать условной агрегации для этого:

SELECT u.uname AS Name, u.udateofbirth AS 'Date of B.', 
     MAX(CASE WHEN p.ptype = 1 THEN p.pnumber END) AS 'Cell phone', 
     MAX(CASE WHEN p.ptype = 2 THEN p.pnumber END) AS 'Home phone', 
     MAX(CASE WHEN p.ptype = 3 THEN p.pnumber END) AS 'Commercial phone', 
     MAX(CASE WHEN p.ptype = 4 THEN p.pnumber END) AS 'Message phone' 
FROM tblUser AS u 
JOIN phonerelation ON u.uid = phonerelation.uid 
JOIN tblPhoneNumber AS p ON p.pid = phonerelation.pid 
GROUP BY 1, 2 
+0

Ty vm por help, но я пытаюсь использовать этот код в другом месте для создания список телефонных телефонов пользователя и разделить на поля в Lazarus (Delphi), я попытался немного его отредактировать, но в своем списке результатов я получаю больше одной строки. То, что мне нужно сократить, когда я выбираю только номера телефонов, пользователь хранится внутри var, поэтому мне не нужно исследовать таблицу пользователей для сравнения id. – douglascast

+0

Alread got it, ty vm. – douglascast

0

Я предлагаю это неуместно иметь много-ко-многим между users и phones. Вместо этого у вас есть только один пользовательский телефон.

Тогда что-то вроде

CREATE TABLE Phones (
     uid ..., 
     type ENUM('cell', 'home', ...), 
     pnumber VARCHAR(20) CHARACTER SET ascii, 
    PRIMARY KEY(uid, type, pnumber) 
); 

SELECT u.uname, ... 
     GROUP_CONCAT(CONCAT(p.type, ': ', p.number) SEPARATOR ', ') AS 'Phone(s)' 
    FROM Users u 
    LEFT JOIN Phones p USING(uid) 
    GROUP BY uid 

С PRIMARY KEY(uid, type), вместо этого, он будет ограничивать каждый пользователь к одному номерам сотовых для одного пользователя. (Это может быть желательной особенностью.)