如何使用mysql中的连接并避免响应中的重复条目

时间:2017-08-26 06:16:32

标签: mysql sql

我已尝试过这两种情况并继续为每个信用数据条目获取重复:

SELECT DISTINCT * FROM
FROM  `mediaDATA` 
LEFT JOIN media_creditsDATA ON mediaDATA.id = media_creditsDATA.media_id

SELECT * 
FROM  `mediaDATA` 
LEFT JOIN media_creditsDATA ON mediaDATA.id = media_creditsDATA.media_id

enter image description here

4 个答案:

答案 0 :(得分:8)

首先,使用distinct *是违反直觉的,您实际上是在选择表中的每一行,然后消除重复的行。尽量避免使用它。

因为您已尝试distinct,所以它消除了您在表格中开始使用重复数据的可能性。 查看截图我认为行不重复。它们在某些列上可能相同但不能完全相同。例如。

media:
id          name
----------- ---------------
1           mediaA
2           mediaB
3           mediaC

media_creditsDATA:
media_id    credit_id  name
----------- ----------- ---------------
1           1           good credit
1           2           ok credit
2           3           bad credit
3           4           no credit

如果您使用distinct执行以下sql,结果是相同的:

SELECT *
FROM  media
INNER JOIN media_creditsDATA ON media.id = media_creditsDATA.media_id

结果:

id          name            media_id    credit_id  name
----------- --------------- ----------- ----------- ---------------
1           mediaA          1           1           good credit
1           mediaA          1           2           ok credit
2           mediaB          2           3           bad credit
3           mediaC          3           4           no credit

如果只查看结果表中的前三列,那么确定存在重复记录,但是如果查看所有列则不会。如您所见,媒体表与media_creditsDATA表具有一对多关系。 结果表包含共享相同列列的记录,但没有重复记录。

所以我认为这种情况下的问题不在于您加入的方式如何过滤您的结果。例如,您在media_creditsDATA表中寻找的信用记录的子集是什么?或者你可能不在乎,你只记录每个媒体记录的最高credit_id。

SELECT * 
FROM  media
INNER JOIN (
    select media_id, max(credit_id) as highest_credit_id from media_creditsDATA 
     group by media_id )media_creditsDATA ON media.id = media_creditsDATA.media_id

你得到:

id          name            media_id    highest_credit_id
----------- --------------- ----------- --------------
1           mediaA          1           2
2           mediaB          2           3
3           mediaC          3           4

答案 1 :(得分:2)

如果您不想要重复的行,则应该仅为您真正需要的值使用不同的显式列名称 例如:

  SELECT distinct id, company_id, associated_company_id, title, year,  `desc`, media_file
  FROM  mediaDATA 
  LEFT JOIN media_creditsDATA ON mediaDATA.id = media_creditsDATA.media_id

答案 2 :(得分:0)

select * from mediaDATA LEFT JOIN media_creditsDATA 
ON mediaDATA.id = media_creditsDATA.media_id
where mediaDATA.id in (
select DISTINCT(media_id)
from media_creditsDATA 
)

大多数人会说你应该在主Select上的id上添加一个DISTINCT。你可以试试,但我很确定它会降低性能。

答案 3 :(得分:0)

您在第一个语句中遇到重复项,因为media_creditsDATA表中有多个行具有相同的media_id,因为它不是media_creditsData的PK。这个表的非关键数据在所有media_ids中可能是相同的(这将是一个奇怪的模型),但我们当然不能这样认为。鉴于此,为此目的,不同的将是不可靠的。

您有几个选择:

从media_creditsDATA中选择一个不同的字段子集并加入其中,例如:

select * 
from mediaData
LEFT OUTER JOIN 
(select distinct media_id, field1, field2, field3 from media_creditsDATA) t
ON t.media_id = mediaData.id

只要所需字段具有相同media_id的记录之间没有变化,这将起作用。如果有变化,您将再次看到重复项。

更可靠的选择是确定哪些聚合标准对media_creditsDATA记录有意义。如果您不希望存在多条记录,那么您需要哪种记录?也许有办法找到最新的,第一个,等等?此查询可能如下所示:

Select *
  from mediaData
  LEFT OUTER JOIN 
  (select * 
     from media_creditsDATA
     inner join 
     (select media_id, max(%some_date% or %some_id%
        from media_creditsDATA
       group by media_id) mc_t
     on mc_t.media_id = media_creditsDATA.media_id
    and mc_t.%aggregated_column% = media_creditsDATA.%same_column) t
    ON t.media_id = mediaData.id

这将确保子查询将返回正好1或0行。