我有一张表,需要在不同的行上显示结果,在一列中必须存在不同的键值。
我每天通过REST API从另一个系统获取此表一次,并在我的MySQL DB中进行如下查找(简化):
+----+------+------------+-------+
| ID | type | date | value |
+----+------+------------+-------+
| 1 | A | 2019-06-01 | 1 |
| 2 | B | 2019-06-01 | 2 |
| 3 | A | 2019-06-02 | 4 |
| 4 | B | 2019-06-03 | 5 |
| 9 | A | 2019-06-09 | 11 |
| 10 | B | 2019-06-09 | 14 |
| 11 | A | 2019-06-24 | 99 |
+----+------+------------+-------+
现在,我需要一个选择,该选择仅在同时存在类型A和类型B的值的情况下全部生成。结果应如下所示:
+------------+-------+--------+----+------+------------+-------+
| date | typeA | valueA | ID | type | date | value |
+------------+-------+--------+----+------+------------+-------+
| 2019-06-01 | A | 1 | 2 | B | 2019-06-01 | 2 |
| 2019-06-09 | A | 11 | 10 | B | 2019-06-09 | 14 |
+------------+-------+--------+----+------+------------+-------+
使用子选择...对于大表来说可能不是个好主意...但我不确定。
SELECT * from
(SELECT date as dateA, value as valueA from V1 where type = 'A') AS subA,
(SELECT date as dateB, value as valueB from V1 where type = 'B') AS subB
WHERE dateA = dateB
创建两个临时表,然后加入一个联接。但是需要时间来创建两个表以及两个新临时表之间的联接。
CREATE TEMPORARY table tA SELECT date, type as typeA, value as valueA from V1 WHERE type = 'A';
CREATE TEMPORARY table tB SELECT date, type as typeB, value as valueB from V1 WHERE type = 'B';
SELECT * from tA
INNER JOIN tB on tA.date = tB.date;
仅在临时表上创建并将其用于使用主表的联接:
CREATE TEMPORARY table tB SELECT * from V1 WHERE type = 'B';
SELECT * from V1
INNER JOIN tB on V1.date = tB.date
where V1.type = 'A'
我的哪个想法最适合大型桌子,还是有更好的解决方案?
谢谢。
答案 0 :(得分:2)
您需要一个自我内部联接
select select v1.date,v1.type as typeA, v1.value as valueA,
v2.id, v2.type as typeB, v2.date, v2.value
from v v1 join v v2 -- v is table name
on v1.date = v2.date
and v1.type = 'A' and v2.type = 'B';
+------------+-------+--------+----+------+------------+-------+
| date | typeA | valueA | ID | type | date | value |
+------------+-------+--------+----+------+------------+-------+
| 2019-06-01 | A | 1 | 2 | B | 2019-06-01 | 2 |
| 2019-06-09 | A | 11 | 10 | B | 2019-06-09 | 14 |
+------------+-------+--------+----+------+------------+-------+
答案 1 :(得分:1)
一种有效的方法可能是基于不同计数= 2的日期与ype A的表itesel以及b类型的一个tyme之间的内部联接
select t.date, t1.type typeA, t1.value valueA, t2.type typeB, t2.value valueB,
from (
select date
from my_table
group by date
having count(distinct type) = 2
) t
inner join my_table t1 on t1.date = t.date and type='A'
inner join my_table t2 on t2.date = t.date and type='B'
答案 2 :(得分:1)
这可能不是最显而易见的查询。
但这很有意义,因为您将重点放在日期上并将类型与日期合并。
性能将非常取决于所使用的未知索引。
SELECT
*
FROM (
SELECT
date
, MAX(CASE WHEN type = 'A' THEN type END) AS typeA
, MAX(CASE WHEN type = 'A' THEN value END) AS valueA
FROM
your_table
WHERE
type = 'A'
GROUP BY
date
) AS a_type
INNER JOIN (
SELECT
date
, MAX(CASE WHEN type = 'B' THEN type END) AS typeB
, MAX(CASE WHEN type = 'B' THEN value END) AS valueB
FROM
your_table
WHERE
type = 'B'
GROUP BY
date
) AS b_type
ON
a_type.date = b_type.date
结果
| date | typeA | valueA | date | typeB | valueB |
| ---------- | ----- | ------ | ---------- | ----- | ------ |
| 2019-06-01 | A | 1 | 2019-06-01 | B | 2 |
| 2019-06-09 | A | 11 | 2019-06-09 | B | 14 |
请参阅demo
答案 3 :(得分:1)
如果每个日期只能有每种类型的一种(即同一日期不能有2个“ A”或2个“ B”),则可以按日期分组并使用条件汇总来获取值用于不同的类型。
select
date,
max(case when type = 'A' then id end) idA,
max(case when type = 'A' then value end) valueA,
max(case when type = 'B' then id end) idB,
max(case when type = 'B' then value end) valueB
from V1
where type in ('A', 'B') -- only necessary if other types exist
group by date
having count(distinct type) = 2