开发者

Merge SQL results by creating new field?

I'd like to take two records like this:

Id   Fname  Lname 开发者_C百科 Email
------------------------------------
1    John   Doe    jdoe@example.com
2    John   Doe    doej1@place.net

And combine them in such a way that I have only one record:

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

As you can see, this would add a field to my record that otherwise does not exist in the database. Is this possible or do I have to find another way?

NOTE: I am not able to change the database structure in any way.


The database product and version makes all the difference here. Assuming that you are using something that supports ranking functions (e.g. 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

If you are not using a product that supports ranking functions (e.g. MySQL), then it is trickier. One solution that should work on almost all database systems would be:

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


If you're using SQL Server, see this article: http://support.microsoft.com/kb/175574

It's got an example with different data, but the task is the same. You can usually find examples for other RDBMS's by searching for "Rotate Table [rdbmstype]" on Google or Bing


    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

Probably a little inefficient, but it'll get the job done.


In MySQL you can use GROUP_CONCAT():

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

If you need emails in separate fields, you can split resulting emails string in your programming environment (like explode(',', $result['emails']) in PHP), or use self-join (works only for 2 email fields):

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

adding contraption:

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

to get rid of duplicate email pairs.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜