2015-05-13 21 views
1

我有三個表患者表:其中包含我的病人的名字,控制表:它表示可以得出每個疾病的UI控件,和ControlsValues表其中載有針對每個患者如何行轉換爲列,並詢問他們在MySQL

控件的值允許有一些數據患者

|ID | Name | 
|-----------| 
| 1 | Ara | 
| 2 | Sada | 

控制

|ID | Text | Type  | 
|-----------|----------| 
| 1 | age | textbox | 
| 2 |alergy| checkbox | 

然後controlsValues表這是我想在

|ID | contrlId | value | patientId | 
|---------------|----------|-----------| 
| 1 | 1  | 23  | 1   | 
| 2 | 2  | true  | 1   | 
| 3 | 1  | 26  | 2   | 
| 4 | 2  | false | 2   | 

這裏查詢時,我想回到從ControlsValues表患者已在(controlId=1 AND value=23) and (controlId=2 AND value=true)出現我的問題這種情況下,條件是在兩行而不是兩列,這是不可能的,所以我希望根據controlId將行更改爲列,但我不知道如何,我一直在尋找2天,並看到了很多樣本​​,但他們中沒有人幫助我解決我的問題

回答

-1

解決這個問題的一個方法是使用子查詢

select patientId from controlValues 
where controlId=1 AND value=23 
and patientId in (
    select patientId 
    from controlValues 
    where controlId=2 and value=true 
) 
+0

我試過這種方式,和它的作品.... WOW –

1

考慮以下(我會忽略其他表現在):

CREATE TABLE pcv 
(patient_id INT NOT NULL 
,control_id INT NOT NULL 
,value VARCHAR(12) NOT NULL 
,PRIMARY KEY(patient_id,control_id) 
); 

INSERT INTO pcv VALUES 
(1,1,'23'), 
(1,2,'true'), 
(2,1,'26'), 
(2,2,'false'); 

SELECT * FROM pcv; 
+------------+------------+-------+ 
| patient_id | control_id | value | 
+------------+------------+-------+ 
|   1 |   1 | 23 | 
|   1 |   2 | true | 
|   2 |   1 | 26 | 
|   2 |   2 | false | 
+------------+------------+-------+ 

有兩個標準的解決方案。首先是速度較慢,但​​更簡單的寫:

解決方案1:

SELECT patient_id 
    , MAX(CASE WHEN control_id = 1 THEN value END) age 
    , MAX(CASE WHEN control_id = 2 THEN value END) allergy 
    FROM pcv 
GROUP 
    BY patient_id; 
+------------+------+---------+ 
| patient_id | age | allergy | 
+------------+------+---------+ 
|   1 | 23 | true | 
|   2 | 26 | false | 
+------------+------+---------+ 

解決方案2:

SELECT pcv1.patient_id 
    , pcv1.value age 
    , pcv2.value allergy 
    FROM pcv pcv1 
    LEFT 
    JOIN pcv pcv2 
    ON pcv2.patient_id = pcv1.patient_id 
    AND pcv2.control_id = 2 
WHERE pcv1.control_id = 1; 
+------------+-----+---------+ 
| patient_id | age | allergy | 
+------------+-----+---------+ 
|   1 | 23 | true | 
|   2 | 26 | false | 
+------------+-----+---------+ 

注意採用的EAV模型時,它仍然是很好的做法,利用適當的數據類型在可能的情況。所以你可能有一個存儲日期信息的表,另一個存儲字符串信息。

+0

你的解決方案似乎更先進的,但我不知道我的控件上它是動態的名稱查詢的名稱,它每個用戶的變化,這是關於你的第一個解決方案,第二個更接近我想要的 –

+0

無論哪種方式,這只是一個聯接。 – Strawberry

1

另一種方法是計算匹配的行數,如果您需要確保它們滿足您設定的標準數量以上 - 畢竟您可能有多個匹配項!如果您想變得複雜一些,請設置一個變量,該變量具有最少的匹配記錄數,並從那裏開始。

SELECT P.ID, P.Name, COUNT(*) 
FROM Patients P 
JOIN ControlsValues V ON V.patientId = P.ID 
WHERE (V.value = 23 AND V.ControlId = 1) 
OR (V.value = 'true' AND V.ControlId = 2) 
GROUP BY P.ID, P.Name 
HAVING COUNT(*) > 1 
1

您可以通過連接將行表示爲列。

select 
    * 
from controlsValues cv1 
join controlsValues cv2 
    on cv1.patientId = cv2.patientId 
    and cv1.id <> cv2.id -- remove duplicates 
where 
    cv1.contrlId = 1 AND cv1.value = 23 
    and cv2.contrlId = 2 AND cv2.value = 'true' 
; 

現在你可以看到你的患者誰是23歲,並有過敏。

+0

這也可以正常工作,但是如果查詢在兩行以上,它就會變成一個迷宮,謝謝 –

+0

當你給表格賦予聰明的名字時,它變得很明顯,例如:'select * from controlsValues as age'' than' age.value = 23'等... –

+0

如果你關於'和cv1.id <> cv2.id - 刪除重複項,你可以用另一種方式達到它:'select * from cv1 where cv1.contrlId = 1'比在cv2.contrlId = 2上加入cv2要好。 –

2

試試這個

 
    select * from controlvalues; 

    +----+----------+-------+-----------+ 
    | id | contrlId | value | patientId | 
    +----+----------+-------+-----------+ 
    | 1 |  1 | 23 |   1 | 
    | 2 |  2 | true |   1 | 
    | 3 |  1 | 26 |   2 | 
    | 4 |  2 | false |   2 | 
    | 5 |  1 | 23 |   3 | 
    | 6 |  2 | true |   3 | 
    +----+----------+-------+-----------+ 
    6 rows in set (0.00 sec) 

的mysql> SELECT cv1.patientId P1,cv1.contrlId CTRL1,cv1.value VAL1,cv2.patientId P2,cv2.contrlId CTRL2,CV2。value val2 FROM controlvalues cv1,controlvalues cv2 WHERE cv1.patientId = cv2.patientId and cv1.contrlId = 2 and cv1.value ='true'and cv2.contrlId = 1 and cv2.value ='23';

+------+-------+------+------+-------+------+ 
| p1 | ctrl1 | val1 | p2 | ctrl2 | val2 | 
+------+-------+------+------+-------+------+ 
| 1 |  2 | true | 1 |  1 | 23 | 
| 3 |  2 | true | 3 |  1 | 23 | 
+------+-------+------+------+-------+------+ 
2 rows in set (0.00 sec) 

+0

這也是可行的,但如果我想做第三個條件,我應該進行另一個連接以便進行查詢 –