SQL select 来自多个列的不同值
SQL select DISTINCT values from multiple columns
希望我写对了。
我正在尝试为帖子制作标签,例如在 instagram 中。
用户最多可以添加 3 个标签。我将它们保存在单独的数据库列中。 (tag1/tag2/tag3) 之后只想显示不同的值及其总数。不管它们位于哪一列。
例如我有 2 个不同的 mysql 行(帖子)
第 1 行有:tag1 = house,tag2 = kitchen,tag3 = null
第 2 行有:标签 1 = 家,标签 2 = 花园,标签 3 = 房子
我想显示house(2)/kitchen(1)/garden(1)/home(1)
我得到的结果:house(1)/kitchen(1)/garden(1)/home(1)/house(1) 因为每个 house
都在不同的列中。
我有数据库 table (diy_posts):
Image
我的想法sql查询:
SELECT DISTINCT p.tag1 as tag1, p.tag2 as tag2, p.tag3 as tag3,
SUM(CASE WHEN p.tag1=tag1 OR p.tag2=tag2 OR p.tag3=tag3 THEN 1 ELSE 0 END) as count FROM diy_posts p GROUP BY p.id
并像这样显示它们:
foreach ($diyTags as $tag) {
echo $tag['tag1']; echo $tag['count'];
echo $tag['tag2']; echo $tag['count'];
echo $tag['tag3']; echo $tag['count'];
}
您可以通过旋转 table:
select tag, count(*)
from ((select p.tag1 as tag from diy_posts p) union all
(select p.tag2 as tag from diy_posts p) union all
(select p.tag3 as tag from diy_posts p)
) pt
group by tag;
需要这样做表明您可能没有正确的数据模型。更典型的模型是:
create table postTags (
postTagid int auto_increment primary key,
postId int,
tag_number int,
tag varchar(255)
);
我确实注意到,这将需要一个触发器来将标签的数量限制为三个——如果确实需要的话。这也使得数据库可以通过简单地定义唯一约束或索引来防止重复标记。
将其变成单列并求和:
select tag, count(*) as counts
from
(
SELECT p.tag1 as tag FROM diy_posts
UNION ALL
SELECT p.tag2 as tag FROM diy_posts
UNION ALL
SELECT p.tag3 as tag FROM diy_posts
) tmp
GROUP BY tag;
使用 Distinct 关键字无法获得您想要的输出。
- 此外,对于所需的输出,您的 Table 模式是错误的。它必须是垂直的而不是水平的。
- 仍然在现有的 Table 结构中,您可以通过在 ServerSide 中进行比较和计数过程来获得所需的输出(PHP 似乎在您的情况下)。
我猜这是在现有模式中实现输出的唯一方法。
- 但是,当标签和 post 大小增加时,这会破坏性能,因此您需要更改 table 架构,或者您也可以接近 child table。
希望我写对了。
我正在尝试为帖子制作标签,例如在 instagram 中。
用户最多可以添加 3 个标签。我将它们保存在单独的数据库列中。 (tag1/tag2/tag3) 之后只想显示不同的值及其总数。不管它们位于哪一列。
例如我有 2 个不同的 mysql 行(帖子)
第 1 行有:tag1 = house,tag2 = kitchen,tag3 = null
第 2 行有:标签 1 = 家,标签 2 = 花园,标签 3 = 房子
我想显示house(2)/kitchen(1)/garden(1)/home(1)
我得到的结果:house(1)/kitchen(1)/garden(1)/home(1)/house(1) 因为每个 house
都在不同的列中。
我有数据库 table (diy_posts):
Image
我的想法sql查询:
SELECT DISTINCT p.tag1 as tag1, p.tag2 as tag2, p.tag3 as tag3,
SUM(CASE WHEN p.tag1=tag1 OR p.tag2=tag2 OR p.tag3=tag3 THEN 1 ELSE 0 END) as count FROM diy_posts p GROUP BY p.id
并像这样显示它们:
foreach ($diyTags as $tag) {
echo $tag['tag1']; echo $tag['count'];
echo $tag['tag2']; echo $tag['count'];
echo $tag['tag3']; echo $tag['count'];
}
您可以通过旋转 table:
select tag, count(*)
from ((select p.tag1 as tag from diy_posts p) union all
(select p.tag2 as tag from diy_posts p) union all
(select p.tag3 as tag from diy_posts p)
) pt
group by tag;
需要这样做表明您可能没有正确的数据模型。更典型的模型是:
create table postTags (
postTagid int auto_increment primary key,
postId int,
tag_number int,
tag varchar(255)
);
我确实注意到,这将需要一个触发器来将标签的数量限制为三个——如果确实需要的话。这也使得数据库可以通过简单地定义唯一约束或索引来防止重复标记。
将其变成单列并求和:
select tag, count(*) as counts
from
(
SELECT p.tag1 as tag FROM diy_posts
UNION ALL
SELECT p.tag2 as tag FROM diy_posts
UNION ALL
SELECT p.tag3 as tag FROM diy_posts
) tmp
GROUP BY tag;
使用 Distinct 关键字无法获得您想要的输出。
- 此外,对于所需的输出,您的 Table 模式是错误的。它必须是垂直的而不是水平的。
- 仍然在现有的 Table 结构中,您可以通过在 ServerSide 中进行比较和计数过程来获得所需的输出(PHP 似乎在您的情况下)。
我猜这是在现有模式中实现输出的唯一方法。 - 但是,当标签和 post 大小增加时,这会破坏性能,因此您需要更改 table 架构,或者您也可以接近 child table。