Объединить результаты SQL путем создания нового поля? - PullRequest
4 голосов
/ 13 июля 2011

Я бы хотел взять две записи, подобные этой:

Id   Fname  Lname  Email
------------------------------------
1    John   Doe    jdoe@example.com
2    John   Doe    doej1@place.net

И объединить их таким образом, чтобы у меня была только одна запись:

Id   Fname  Lname Email1            Email2
---------------------------------------------------
1    John   Doe   jdoe@example.com  doej@place.net

Как вы можете видеть, это добавит поле к моей записи, которое иначе не существует в базе данных.Возможно ли это, или мне нужно найти другой способ?

ПРИМЕЧАНИЕ. Я не могу каким-либо образом изменить структуру базы данных.

Ответы [ 4 ]

2 голосов
/ 13 июля 2011

Продукт базы данных и версия имеют все значение здесь.Предполагая, что вы используете что-то, поддерживающее функции ранжирования (например, SQL Server 2005 +)

Select FName, LName
    , Min( Case When Rnk = 1 Then Z.Email End ) As Email1
    , Min( Case When Rnk = 2 Then Z.Email End ) As Email2
From    (
        Select FName, LName, Email
            , Row_Number() Over ( Partition By FName, LName Order By Id ) As Rnk
        From MyTable
        ) As Z
Group By Z.FName, Z.LName

Если вы не используете продукт, поддерживающий функции ранжирования (например, MySQL), то это сложнее.Одним из решений, которое должно работать практически на всех системах баз данных, было бы:

Select FName, LName
    , Min( Case When Rnk = 1 Then Z.Email End ) As Email1
    , Min( Case When Rnk = 2 Then Z.Email End ) As Email2
From    (
        Select FName, LName, Email
            , (Select Count(*)
                From MyTable As T2
                Where T1.FName = T2.FName
                    And T2.LName = T2.LName
                    And T2.Id < T1.Id) + 1 As Rnk
        From MyTable As T1
        ) As Z
Group By Z.FName, Z.LName
0 голосов
/ 13 июля 2011

В MySQL вы можете использовать GROUP_CONCAT():

SELECT Fname, Lname, GROUP_CONCAT(email) emails
FROM tbl
GROUP BY Fname, Lname;

Если вам нужны электронные письма в отдельных полях, вы можете разделить результирующую строку emails в своей среде программирования (например, explode(',', $result['emails']) в PHP), или используйте самосоединение (работает только для 2 полей электронной почты):

SELECT a.Fname, a.Lname, a.Email Email1, b.email Email2
FROM tbl a JOIN tbl b ON a.Fname = b.Fname AND a.Lname = b.Lname AND a.Email != b.Email

добавляя хитрость:

GROUP BY CONCAT(GREATEST(Email1,Email2),LEAST(Email1,Email2))

, чтобы избавиться от дублирующих пар электронной почты.

0 голосов
/ 13 июля 2011
    select x.Id as ID, x.Fname as Fname, x.Lname as Lname, x.Email as Email1, y.Email as email2 from
        (select id, fname, lname, email from table) as x inner join
        (select id, email from table) as y on x.id = y.id and x.email != y.email

Возможно, немного неэффективно, но это сделает работу.

0 голосов
/ 13 июля 2011

Если вы используете SQL Server, см. Эту статью: http://support.microsoft.com/kb/175574

У него есть пример с другими данными, но задача та же. Обычно вы можете найти примеры для других СУБД, выполнив поиск «Повернуть таблицу [rdbmstype]» в Google или Bing

...