1

個人用のテーブル、連絡先の種類 (電子メール、電話など) 用の別のテーブル、および個人の連絡先を保存するためのジャンクション テーブルがあります。

1 つのレコードで各人の電子メール、電話、郵便番号を取得するクエリを作成したいと思います。

だから私は4列の結果セットUserName、Tel、Email、POを持っています

私は SQL Server 2000 を使用しているので、XML はオプションではありません。

これを機能させるための助けをいただければ幸いです。

4

3 に答える 3

1

列に関する有用な詳細を提供できなかったので、推測する必要がありましたが、次のようなものを探していると思います.

WITH Persons(PersonId, UserName) AS
(
SELECT 1, 'Bob' UNION ALL
SELECT 2, 'Bill'
), ContactTypes(ContactTypeId, Name) AS
(
SELECT 1, 'Tel' UNION ALL
SELECT 2, 'Email' UNION ALL
SELECT 3, 'PO'
),PersonContacts(PersonId, ContactTypeId, Value) As
(
SELECT 1,1,CAST('(01223) 123456' AS VARCHAR(50)) UNION ALL
SELECT 1,2,CAST('bob@example.com' AS VARCHAR(50)) UNION ALL
SELECT 1,3,CAST('1 Acacia Avenue' AS VARCHAR(50)) UNION ALL
SELECT 2,1,CAST('(01223) 654321' AS VARCHAR(50)) UNION ALL
SELECT 2,2,CAST('bill@example.com' AS VARCHAR(50)) 
)

/*The above Common Table Expressions are just for demo purposes and so you 
can see the assumptions. They will not work on SQL Server 2000. You just need 
the below.*/
SELECT P.UserName, 
       /*I've just used the Ids rather than bothering to join on ContactTypes*/
       MAX(CASE WHEN C.ContactTypeId = 1 then C.Value END) Tel,
       MAX(CASE WHEN C.ContactTypeId = 2 then C.Value END) Email,
       MAX(CASE WHEN C.ContactTypeId = 3 then C.Value END) PO
FROM Persons P
LEFT JOIN PersonContacts C ON C.PersonId = P.PersonId
GROUP BY P.PersonId,P.UserName

戻り値

UserName Tel                 Email               PO
-------- ------------------- ------------------- ------------------
Bob      (01223) 123456      bob@example.com     1 Acacia Avenue
Bill     (01223) 654321      bill@example.com    NULL
于 2011-04-24T17:43:52.483 に答える
0

私はあなたがこれを望んでいると思います:

SELECT p.username, email.value as email, tel.value as tel, po.value as po
FROM persons p
LEFT JOIN contacts as email ON contacts.person_id = person.id
LEFT JOIN contacts as tel ON contacts.person_id = person.id
LEFT JOIN contacts as po ON contacts.person_id = person.id
WHERE email.type = 'email'
AND tel.type = 'tel'
AND po.type = 'po'

したがって、連絡先テーブルには 3 つの異なる形式の連絡先が含まれているため、基本的に連絡先テーブルに 3 回参加します。これはポリモーフィックなアプローチであり、SQL にうまく対応しません。

このクエリの結果は次のようになります。

username | email           | tel       | po
John     | john@john.com   | 012364342 | 1234AA
Sarah    | sarah@sarah.com | NULL      | NULL

マーティンのソリューションもうまくいくと思いますが、CASE-WHEN-THEN-ENDにはあまり満足していません

于 2011-04-24T17:57:48.380 に答える
0

質問の最初のバージョンで重要な情報を提供しなかったため、スキーマについて推測する必要があります。

想定スキーマ

  • 表: 個人 - ユーザー名 (PK)、...
  • 表: 連絡先 - ContactType ('Tel'、'Email'、'PO')、ContactInfo、ContactID (PK)、...
  • 表: ジャンクション - UserName、ContactID - コンボの PK、各列の FK

可能なクエリ

SELECT P.UserName, T.Tel, E.Email, O.PO
  FROM Persons AS P
  LEFT JOIN (SELECT J.UserName, C.ContactInfo AS Tel
               FROM Contacts AS C
               JOIN Junction AS J ON C.ContactId = J.ContactID
              WHERE C.ContactType = 'Tel') AS T
       ON P.UserName = T.UserName
  LEFT JOIN (SELECT J.UserName, C.ContactInfo AS Email
               FROM Contacts AS C
               JOIN Junction AS J ON C.ContactId = J.ContactID
              WHERE C.ContactType = 'Email') AS E
       ON P.UserName = E.UserName
  LEFT JOIN (SELECT J.UserName, C.ContactInfo AS PO
               FROM Contacts AS C
               JOIN Junction AS J ON C.ContactId = J.ContactID
              WHERE C.ContactType = 'PO') AS O
       ON P.UserName = O.UserName

クエリを適切に機能させるために強制する必要のある複雑な制約がいくつかあることに注意してください。主なものは、特定の人の電子メール アドレスがゼロまたは 1 つ、電話番号がゼロまたは 1 つ、PO (郵便局の住所ですか?) がゼロまたは 1 つであることです。誰かがこれらのエントリのいずれかを複数持っている場合、何が適切な出力であるかを単純に教えてくれません。また、最も単純なバージョンでは、ユーザー名と連絡先の種類の組み合わせに対して一意の制約が必要になるため、制約を適用するのは複雑ですが、これらの列は単一のテーブルにまとめて格納されることはありません。

于 2011-04-24T18:03:33.087 に答える