使用MySQL从一行中的两个表中检索数据

时间:2015-09-02 09:49:10

标签: mysql

我试图从两个表中获取日期,但问题是他们为个人ID返回多行。 我有这样的表格: -

Transaction
-----------
tid|startdate|enddate|status
100|2-9-2015|2-9-2015|success
200|1-9-2015|1-9-2015|failed
300|31-8-2015|31-8-2015|success

Test_Details
------------
id|tid|test_name|test_status
1|100|Test1|yes
2|100|Tes2|no
3|100|Test3|yes
4|200|Test1|no
5|200|Tes2|no
6|200|Test3|yes
7|300|Test1|yes
8|300|Tes2|no
9|300|Test3|no

期望的结果: -

tid|startdate|enddate|status|Test1|Test2|Test3
100|2-9-2015|2-9-2015|success|yes|no|yes
200|1-9-2015|1-9-2015|failed|no|no|yes
300|31-8-2015|31-8-2015|success|yes|no|no

我正在使用此查询: -

select distinct ts.tid as tid, ts.startdate as startdate,
ts.enddate as enddate, ts.status as status, 
CASE WHEN (td.test_name='Test1') THEN test_status END as Test1,
CASE WHEN (td.test_name='Test2') THEN test_status END as Test2,
CASE WHEN (td.test_name='Test3') THEN test_status END as Test3
from transation ts, test_details td where ts.tid =td.id

但是我得到了多行。 这是SQLFiddle演示

4 个答案:

答案 0 :(得分:1)

只要test_details不是临时表,您就可以执行以下操作:

SELECT ts.tid, ts.startdate, ts.enddate, ts.status,
  t1.test_status Test1,
  t2.test_status Test2,
  t3.test_status Test3
 FROM transaction ts
  LEFT JOIN test_details t1 ON (t1.tid=ts.tid AND t1.test_name='Test1')
  LEFT JOIN test_details t2 ON (t2.tid=ts.tid AND t2.test_name='Test2')
  LEFT JOIN test_details t3 ON (t3.tid=ts.tid AND t3.test_name='Test3');

假设transaction.tid是唯一的,并且test_details中的(tid,test_name)对是唯一的。

编辑:回复OP评论“它正在运行,但在大型数据库上运行缓慢”我建议将索引添加到test_details.tid和{ {1}}:

test_details.test_name

此外,如果已知所有三项测试都适用于所有交易,您可能需要使用ALTER TABLE test_details ADD INDEX (tid); ALTER TABLE test_details ADD INDEX (test_name); 代替JOIN

LEFT JOIN

答案 1 :(得分:0)

您可以使用GROUP BY查询,例如使用GROUP_CONCAT聚合函数:

SELECT
  ts.tid as tid,
  ts.startdate as startdate,
  ts.enddate as enddate,
  ts.status as status,
  GROUP_CONCAT(test_status ORDER BY td.test)
FROM
  transation ts LEFT JOIN test_details td ON ts.tid =td.id
GROUP BY
  ts.tid,
  ts.startdate,
  ts.enddate,
  ts.status

或此查询,如果您希望在不同的列中具有状态:

SELECT
  ts.tid as tid,
  ts.startdate as startdate,
  ts.enddate as enddate,
  ts.status as status, 
  MAX(CASE WHEN (td.test_name='Test1') THEN test_status END) as Test1,
  MAX(CASE WHEN (td.test_name='Test2') THEN test_status END) as Test2,
  MAX(CASE WHEN (td.test_name='Test3') THEN test_status END) as Test3
FROM
  transation ts LEFT JOIN test_details td ON ts.tid =td.id
GROUP BY
  ts.tid,
  ts.startdate,
  ts.enddate,
  ts.status

答案 2 :(得分:0)

select 
    ts.tid as tid, 
    ts.startdate as startdate,
    ts.enddate as enddate, 
    ts.status as status, 
    group_concat(test1) test1, 
    group_concat(test2) test2, 
    group_concat(test3) test3 
  from 
    (select 
        ts.tid as tid, 
        ts.status as status, 
        CASE WHEN (td.test_name='Test1') THEN test_status END as Test1,
        CASE WHEN (td.test_name='Tes2') THEN test_status END as Test2,
        CASE WHEN (td.test_name='Test3') THEN test_status END as Test3
      from 
         transation ts 
       join 
         test_details td 
       on ts.tid=td.tid
      ) t 
 group by tid

答案 3 :(得分:0)

您可以在添加group by子句后立即使用自己的查询 -

select distinct ts.tid as tid, ts.startdate as startdate,
ts.enddate as enddate, ts.status as status, 
CASE WHEN (td.test_name='Test1') THEN test_status END as Test1,
CASE WHEN (td.test_name='Test2') THEN test_status END as Test2,
CASE WHEN (td.test_name='Test3') THEN test_status END as Test3
from transation ts, test_details td 
where ts.tid =td.id 
group by ts.tid;