2010-06-02 119 views
3

說幫助我有2個表:需要使用SQL查詢

Person 

- Id 
- Name 

PersonAttribute 

- Id 
- PersonId 
- Name 
- Value 

而且,讓我們說,每個人有2種屬性(比如,性別和年齡)。樣本的記錄是這樣的:

Person->Id = 1 
Person->Name = 'John Doe' 

PersonAttribute->Id = 1 
PersonAttribute->PersonId = 1 
PersonAttribute->Name = 'Gender' 
PersonAttribute->Value = 'Male' 

PersonAttribute->Id = 2 
PersonAttribute->PersonId = 1 
PersonAttribute->Name = 'Age' 
PersonAttribute->Value = '30' 

問題:我該如何查詢該這樣,我得到這樣一個結果:

「李四」,「男」,「30」

回答

4
SELECT p.name, p1.Value, p2.Value 
    FROM Person p, PersonAttribute p1, PersonAttribute p2 
    WHERE p.Id = p1.PersonId AND p.Id = p2.PersonId 
     AND p1.Name = 'Gender' AND p2.Name = 'Age' 
+1

這不能縮放以提取N個通用屬性及其值。 – Timothy 2010-06-02 06:39:35

1

拋開設計,你總是可以得到PIVOT的結果,但你需要知道你預先選擇了多少屬性。

3

我認爲你需要重新設計你的架構。 爲什麼不呢?

Person 

- Id 
- Name 
- Gender 
- Birthday 
... 
+2

+1完全同意。看起來年齡存儲在PersonAttribute-> Value字符串列中,以及諸如「Male」之類的內容(並且您指出這應該是派生出來的) – 2010-06-02 06:33:46

+0

我不同意。 OP設計了一個通用屬性模式,可能使用戶可以定義他們自己的屬性並分配他們自己的值。不過,他的例子是一個很差的例子。 – Timothy 2010-06-02 06:38:53

+0

@ msi77&@martinsmith:模式要求實體A具有0個或更多屬性。 「人」的例子就是這樣一個例子。我用它來簡化我的問題並獲得更快的響應。 – StackOverflowNewbie 2010-06-02 06:49:40

0
SELECT Name, g.Value, a.Value 
FROM Person, 
PersonAttribute g INNER JOIN ON g.Name = "Gender", 
PersonAttribute a INNER JOIN ON a.Name = "Age" 
2

SELECT p.Name,g.Value,a.value中
FROM人員P INNER JOIN PersonAttribute克ON p.Id = g.Id AND g.Name = 「性別」
INNER JOIN PersonAttribute a ON p.Id = a.Id AND a.Name =「Age」

1

看看有沒有簡單的方法來做到這一點。

透視表(已被另一個答覆中提到)的概念基本上是你在找什麼,但透視表需要你知道你要使用的列的名稱。很顯然,當你想利用這種桌子設計的力量時,這是一個問題!

在我以前的生活,我只是看中了列的X號,如20-30,如果他們不存在,則該行集包含了一堆空值。沒什麼大不了。

select piv.name, 
    max(case piv.a_name when 'Gender' then piv.a_value else null end) as Gender, 
    max(case piv.a_name when 'Age' then piv.a_value else null end) as Age, 
    max(case piv.a_name when 'Hobby' then piv.a_value else null end) as Hobby 
from 
(select p.name as name, pa.name as a_name, pa.value as a_value 
from person p, personattribute pa 
where p.id = pa.personid) piv 
group by piv.name 

這將產生像這樣的輸出:

name | gender | age | hobby 
-----------+--------+-----+--------- 
Bob Swift | Male |  | Reading 
John Doe | Male | 30 | 
(2 rows) 

這是非常該死接近你在找什麼。我會將剩下的部分留給應用層。

我也強烈建議您包含屬性名稱作爲返回值的一部分,提供上下文的值。

這類所謂的實體屬性的設計往往最終不得不依靠特定的服務器功能,存儲過程和硬編碼查詢的組合。