如何根据另一列的值获取单行值?
How to get single row of values based on value of another column?
我正在尝试根据 name
列中的值 select value
列中的值。
例如:
mysql> select name, value from rss_feed_property_value where rss_feed_id = 31;
+-------------+---------------+
| name | value |
+-------------+---------------+
| High | 45 |
| Description | Rain And Snow |
| Low | 25 |
| Day | Fri |
| Date | 29 Dec 2017 |
+-------------+---------------+
5 rows in set (0.00 sec)
我几乎通过以下查询实现了这一点:
select
if (rfpv.name = 'Date', rfpv.value, null) as `Date`,
if (rfpv.name = 'High', rfpv.value, null) as `High`,
if (rfpv.name = 'Low', rfpv.value, null) as `Low`,
if (rfpv.name = 'Description', rfpv.value, null) as `Description`
from rss_feed rf
join rss_feed_definition rfd on rf.rss_feed_definition_id = rfd.id
join rss_feed_property_value rfpv on rfpv.rss_feed_id = rf.id
where rfd.type = 'weather'
and rf.id = 31
order by rf.id;
产生以下输出:
+-------------+------+------+---------------+
| Date | High | Low | Description |
+-------------+------+------+---------------+
| NULL | 45 | NULL | NULL |
| NULL | NULL | NULL | Rain And Snow |
| NULL | NULL | 25 | NULL |
| NULL | NULL | NULL | NULL |
| 29 Dec 2017 | NULL | NULL | NULL |
+-------------+------+------+---------------+
5 rows in set (0.00 sec)
我现在如何通过忽略空值只留下一行来使上面的内容变平,如下所示:
+-------------+------+------+---------------+
| Date | High | Low | Description |
+-------------+------+------+---------------+
| 29 Dec 2017 | 45 | 25 | Rain and Snow |
+-------------+------+------+---------------+
我通过以下查询实现了这一点:
select
rf.id as rssFeedId,
(select value
from rss_feed_property_value
where name = 'Date'
and rss_feed_id = rssFeedId) as `Date`,
(select value
from rss_feed_property_value
where name = 'High'
and rss_feed_id = rssFeedId) as `High`,
(select value
from rss_feed_property_value
where name = 'Low'
and rss_feed_id = rssFeedId) as `Low`,
(select value
from rss_feed_property_value
where name = 'Description'
and rss_feed_id = rssFeedId) as `Description`
from rss_feed rf
join rss_feed_definition rfd on rf.rss_feed_definition_id = rfd.id
join rss_feed_property_value rfpv on rfpv.rss_feed_id = rf.id
where rfd.type = 'weather'
and rf.id = 31
group by rf.id
order by rf.id;
不过我不确定这是否是最有效的方法。
只需将 MAX()
放在要折叠在一起的所有内容周围 (MAX()
忽略 NULL
值),并且 GROUP BY
您要将所有内容折叠到的 ID...
SELECT
rf.id,
MAX(if (rfpv.name = 'Date', rfpv.value, null)) AS `Date`,
MAX(if (rfpv.name = 'High', rfpv.value, null)) AS `High`,
MAX(if (rfpv.name = 'Low', rfpv.value, null)) AS `Low`,
MAX(if (rfpv.name = 'Description', rfpv.value, null)) AS `Description`
FROM
rss_feed AS rf
INNER JOIN
rss_feed_definition AS rfd
ON rf.rss_feed_definition_id = rfd.id
INNER JOIN
rss_feed_property_value AS rfpv
ON rfpv.rss_feed_id = rf.id
WHERE
rfd.type = 'weather'
AND rf.id = 31
GROUP BY
rf.id
ORDER BY
rf.id
;
我将字段 rf.id
添加到 SELECT
只是为了更清楚地说明正在做什么。 (所以也添加了关联GROUP BY rf.id
)
按 rf.id
聚合并使用条件聚合。我会在这里使用 CASE
表达式,因为与 MySQL 的 IF
.
相比,这种语法在数据库中得到更广泛的支持
SELECT
rf.id,
MAX(CASE WHEN rfpv.name = 'Date' THEN rfpv.value END) AS Date,
MAX(CASE WHEN rfpv.name = 'High' THEN rfpv.value END) AS High,
MAX(CASE WHEN rfpv.name = 'Low' THEN rfpv.value END) AS Low,
MAX(CASE WHEN rfpv.name = 'Description' THEN rfpv.value END) AS Description
FROM rss_feed rf
INNER JOIN rss_feed_definition rfd
ON rf.rss_feed_definition_id = rfd.id
INNER JOIN rss_feed_property_value rfpv
ON rfpv.rss_feed_id = rf.id
WHERE
rfd.type = 'weather' AND
rf.id = 31
GROUP BY
rf.id
ORDER BY
rf.id;
我正在尝试根据 name
列中的值 select value
列中的值。
例如:
mysql> select name, value from rss_feed_property_value where rss_feed_id = 31;
+-------------+---------------+
| name | value |
+-------------+---------------+
| High | 45 |
| Description | Rain And Snow |
| Low | 25 |
| Day | Fri |
| Date | 29 Dec 2017 |
+-------------+---------------+
5 rows in set (0.00 sec)
我几乎通过以下查询实现了这一点:
select
if (rfpv.name = 'Date', rfpv.value, null) as `Date`,
if (rfpv.name = 'High', rfpv.value, null) as `High`,
if (rfpv.name = 'Low', rfpv.value, null) as `Low`,
if (rfpv.name = 'Description', rfpv.value, null) as `Description`
from rss_feed rf
join rss_feed_definition rfd on rf.rss_feed_definition_id = rfd.id
join rss_feed_property_value rfpv on rfpv.rss_feed_id = rf.id
where rfd.type = 'weather'
and rf.id = 31
order by rf.id;
产生以下输出:
+-------------+------+------+---------------+
| Date | High | Low | Description |
+-------------+------+------+---------------+
| NULL | 45 | NULL | NULL |
| NULL | NULL | NULL | Rain And Snow |
| NULL | NULL | 25 | NULL |
| NULL | NULL | NULL | NULL |
| 29 Dec 2017 | NULL | NULL | NULL |
+-------------+------+------+---------------+
5 rows in set (0.00 sec)
我现在如何通过忽略空值只留下一行来使上面的内容变平,如下所示:
+-------------+------+------+---------------+
| Date | High | Low | Description |
+-------------+------+------+---------------+
| 29 Dec 2017 | 45 | 25 | Rain and Snow |
+-------------+------+------+---------------+
我通过以下查询实现了这一点:
select
rf.id as rssFeedId,
(select value
from rss_feed_property_value
where name = 'Date'
and rss_feed_id = rssFeedId) as `Date`,
(select value
from rss_feed_property_value
where name = 'High'
and rss_feed_id = rssFeedId) as `High`,
(select value
from rss_feed_property_value
where name = 'Low'
and rss_feed_id = rssFeedId) as `Low`,
(select value
from rss_feed_property_value
where name = 'Description'
and rss_feed_id = rssFeedId) as `Description`
from rss_feed rf
join rss_feed_definition rfd on rf.rss_feed_definition_id = rfd.id
join rss_feed_property_value rfpv on rfpv.rss_feed_id = rf.id
where rfd.type = 'weather'
and rf.id = 31
group by rf.id
order by rf.id;
不过我不确定这是否是最有效的方法。
只需将 MAX()
放在要折叠在一起的所有内容周围 (MAX()
忽略 NULL
值),并且 GROUP BY
您要将所有内容折叠到的 ID...
SELECT
rf.id,
MAX(if (rfpv.name = 'Date', rfpv.value, null)) AS `Date`,
MAX(if (rfpv.name = 'High', rfpv.value, null)) AS `High`,
MAX(if (rfpv.name = 'Low', rfpv.value, null)) AS `Low`,
MAX(if (rfpv.name = 'Description', rfpv.value, null)) AS `Description`
FROM
rss_feed AS rf
INNER JOIN
rss_feed_definition AS rfd
ON rf.rss_feed_definition_id = rfd.id
INNER JOIN
rss_feed_property_value AS rfpv
ON rfpv.rss_feed_id = rf.id
WHERE
rfd.type = 'weather'
AND rf.id = 31
GROUP BY
rf.id
ORDER BY
rf.id
;
我将字段 rf.id
添加到 SELECT
只是为了更清楚地说明正在做什么。 (所以也添加了关联GROUP BY rf.id
)
按 rf.id
聚合并使用条件聚合。我会在这里使用 CASE
表达式,因为与 MySQL 的 IF
.
SELECT
rf.id,
MAX(CASE WHEN rfpv.name = 'Date' THEN rfpv.value END) AS Date,
MAX(CASE WHEN rfpv.name = 'High' THEN rfpv.value END) AS High,
MAX(CASE WHEN rfpv.name = 'Low' THEN rfpv.value END) AS Low,
MAX(CASE WHEN rfpv.name = 'Description' THEN rfpv.value END) AS Description
FROM rss_feed rf
INNER JOIN rss_feed_definition rfd
ON rf.rss_feed_definition_id = rfd.id
INNER JOIN rss_feed_property_value rfpv
ON rfpv.rss_feed_id = rf.id
WHERE
rfd.type = 'weather' AND
rf.id = 31
GROUP BY
rf.id
ORDER BY
rf.id;