如何在保持唯一行的同时进行内部连接

uqcuzwp8  于 2021-06-21  发布在  Mysql
关注(0)|答案(2)|浏览(246)

我有一个三元关系,在这个关系中,我建立了报价、简介和技能之间的关系。三元关系表,称为 ternary 例如,将三个表的id作为主键。它可能看起来像这样:

id_Offer    -   id_Profile  -   id_Skill
1           -   1           -   1
1           -   1           -   2
1           -   1           -   3
1           -   2           -   1
2           -   1           -   1
2           -   3           -   2
2           -   1           -   3
2           -   5           -   1
[and so on, there would be more registers for each id_Offer from Offer but I want to limit the example]

所以我一共有2个报价,每一个都有一些简介。
餐桌上的优惠如下所示:

Offer   -   business_name
1       -   business-1
2       -   business-1
3       -   business-1
4       -   business-1
5       -   business-2 
6       -   business-2 
7       -   business-2 
8       -   business-3

所以当我做一个像

select distinct id_offer, business_name, COUNT(*)
FROM Offer
GROUP BY business_name
Order by COUNT(*);

我有四个工作机会。
现在如果我想考虑一些个人资料,我必须加入我的三元关系。但即使我做了如下简单的事情

select distinct business_name
from Offer
INNER JOIN  ternary ON Offer.id_Offer = ternary.id_Offer
GROUP BY business_name
WHERE business_name =  'business-1'

不管我在小组里放了什么,或者我写了什么,我都得不到我想要的。事实上,对于business-1,我有4个报价。现在在三元组中只出现了两个。因此,它应该返回2个独特的提供这个名字没有过滤配置文件。
但是我得到了8个报价,因为这是它在三元表中出现的次数,id\u报价是匹配的。
这应该怎么做?如果我不需要过滤器,我可以简单地单独查看报价表。但是,如果我需要按id\u skill或id\u profile进行筛选,并希望返回业务名称,该怎么办?
我见过这样的解决办法,但我不能使他们工作,我不明白是什么问题 ? 如果mariadb在这个意义上是一样的,我找不到关于它的信息,因为我不知道这个操作是如何调用的。当我尝试为我的数据构建查询时,我得到:

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '? ORDER BY COUNT(*) DESC' at line 1

但正如我所说的,很难把“?”当作。。。接线员?功能?

vsaztqbk

vsaztqbk1#

你是说你想看到一个特定的业务提供,但你想限制这些根据某些个人资料或技能?
我们将查询结果限制在 WHERE 条款。如果我们想在另一个表中查找数据,我们使用 IN 或者 EXISTS . 例如:

select *
from offer
where business_name = 'business-1'
and id_offer in
(
  select id_offer
  from ternary
  where id_profile = 1
    and id_skill = 2
);
syqv5f0l

syqv5f0l2#

有两种基本的解决办法。

SELECT
  o.business_name,
  COUNT(DISTINCT o.id_offer)   AS unique_offers
FROM
  Offer     AS o
INNER JOIN
  ternary   AS t
    ON t.id_Offer = o.id_Offer
WHERE
      o.business_name = 'business-1'
  AND t.id_profile IN (1, 2, 3, 5)
GROUP BY
  o.business_name

这是最简单的写作和思考。但是,它也可以是相当密集的,因为你仍然加入每一行中 offer 最多4行 ternary -创建8行进行聚合和处理 DISTINCT .
“更好的”(在我看来)方法是过滤然后聚合 ternary 子查询中的表。

SELECT
  o.business_name,
  COUNT(*)         AS unique_offers
FROM
  Offer     AS o
INNER JOIN
(
  SELECT id_Offer
    FROM ternary
   WHERE id_profile IN (1, 2, 3, 5)
GROUP BY id_Offer
)
  AS t
    ON t.id_Offer = o.id_Offer
WHERE
  o.business_name = 'business-1'
GROUP BY
  o.business_name

这确保了 t 任何一个报价只有一行。这又意味着 offer 只加入一行 t ; 没有重复。这又意味着没有必要使用 COUNT(DISTINCT) 并减轻了一些开销(通过将其移动到内部查询的 GROUP BY ).

相关问题