连接两个表的工作查询是完美的,除了我无法摆脱重复项

Posted

技术标签:

【中文标题】连接两个表的工作查询是完美的,除了我无法摆脱重复项【英文标题】:Working Query that joins two tables is perfect except I can't get rid of duplicates 【发布时间】:2011-06-19 00:03:04 【问题描述】:

我有一个 CarComparison 网站,可以从其他汽车网站获取信息。它提取的其中一个提要来自一个网站,该网站允许放置广告的人多次更新它。通常每 10 到 14 天更新一次汽车。

无论如何,我对他们数据的唯一访问是通过 RSS 提要,我从中解析和提取可用数据。我每分钟都会收到它,里面通常有 15 辆左右的新车。

当我进行导入以查看汽车是否已经在系统上时,没有简单的方法。我确实捕获了原始 ID,以便稍后检查。

我为加入表而运行的查询是:

SELECT DISTINCT cc_detail.original_id, cc_detail.year, cc_detail.price, cc_detail.make, cc_detail.model, cc_detail.referrer_site, wposts . *
FROM cc_posts wposts
LEFT JOIN cc_posts_detail cc_detail ON ( wposts.ID = cc_detail.post_id )
WHERE 1 =1
AND (
cc_detail.year >1949
)
AND (
cc_detail.price >0
)
AND cc_detail.referrer_site = 'CarSiteX'
AND wposts.post_status = 'publish'
AND wposts.post_type = 'post'
AND wposts.post_date < NOW( )
AND cc_detail.year <=2011
AND wposts.post_title NOT LIKE 'Ac%'
AND cc_detail.make != ''
AND cc_detail.model != ''
AND (
cc_detail.price +0
) >100
AND (
wposts.post_date > "2011/01/02 "
)
ORDER BY cc_detail.original_id ASC
LIMIT 30 , 300

问题是我不知道如何更改查询,以便每个 original_id 值只提取一行。 CarSiteX 上的投注者已经更新了他/她的车几次,我最终每次都为同一辆车排了一排。我确实有唯一的 original_id,那么如何更改上述查询以仅获取 cc_posts_detail 表中每个 original_id 值的最新行?

以下是一些显示问题的示例行:

original_id  year  price  make  model  referrer_site  ID  post_author  post_date  post_date_gmt  post_content  post_title  post_excerpt  post_status  comment_status  ping_status  post_password  post_name  to_ping  pinged  post_modified  post_modified_gmt  post_content_filtered  post_parent  guid  menu_order  post_type  post_mime_type  comment_count
1143583  2000  2900  lexus  is200  CarSitex  9633341  1  2011-01-19 05:34:01  2011-01-19 12:34:01     2000 Manual 2.0 Petrol 136k miles NCT  039 d 0...  Lexus Is200 2000     publish  open  open     lexus-is200-2000-        2011-01-19 05:34:01  2011-01-19 12:34:01     0     0  post     0
1149513  1997  2000  mitsubishi  colt  CarSitex  8978523  1  2011-01-05 12:26:01  2011-01-05 19:26:01     1600cc mivec twin cam 16valve. 175 bhp.Four br...  Mitsubishi Colt 1997     publish  open  open     mitsubishi-colt-1997-        2011-01-05 12:26:01  2011-01-05 19:26:01     0     0  post     0
1149513  1997  2000  mitsubishi  colt  CarSitex  9416296  1  2011-01-14 12:04:01  2011-01-14 19:04:01     1600cc mivec twin cam 16valve. 175 bhp.Four br...  Mitsubishi Colt 1997     publish  open  open     mitsubishi-colt-1997-        2011-01-14 12:04:01  2011-01-14 19:04:01     0     0  post     0
1156791  2004  5950  ford  focus  CarSitex  9163527  1  2011-01-08 10:04:01  2011-01-08 17:04:01     2004 FORD FOCUS 1.4 4 DOOR 78333 MILES NCT D 1...  Ford Focus 2004     publish  open  open     ford-focus-2004-        2011-01-08 10:04:01  2011-01-08 17:04:01     0     0  post     0

看到有两辆三菱小马是同一辆车....

很抱歉,如果我输入了太多信息,或者这个问题太多了... 新手。任何帮助表示赞赏!

cc_post_details 结构:

id  int(4) 
referrer_site   varchar(100) 
original_id     bigint(8) 
dealer  varchar(255) 
make    varchar(100) 
model   varchar(100) 
colour  varchar(100) 
year    varchar(8) 
engine_size     int(4) 
mileage     int(4) 
price   int(4) 
location    varchar(100) 
fuel_type   varchar(50) 
body_type   varchar(50) 
transmission    varchar(50) 
doors   int(4) 
image_base_url  varchar(255) 
image_main  text 
image_thumb     text 
post_id     int(4) 
date_added  datetime 
underscore_beepbeep_pos     int(11)

cc_posts 结构

    ID  bigint(20) 
post_author     bigint(20) 
post_date   datetime 
post_date_gmt   datetime 
post_content    longtext 
post_title  text 
post_excerpt    text 
post_status     varchar(20) 
comment_status  varchar(20) 
ping_status     varchar(20) 
post_password   varchar(20) 
post_name   varchar(200) 
to_ping     text 
pinged  text 
post_modified   datetime 
post_modified_gmt   datetime 
post_content_filtered   text 
post_parent     bigint(20) 
guid    varchar(255) 
menu_order  int(11) 
post_type   varchar(20) 
post_mime_type  varchar(100) 
comment_count   bigint(20) 

【问题讨论】:

【参考方案1】:

使用GROUP BY cc_detail.original_id

【讨论】:

【参考方案2】:

问题出在您的 select 语句中的 wposts.* 上(更不用说 select * 是 bad)。关键字Distinct 将只显示不同的行。当您将 wposts.* 添加到查询中时,它会提取 ID、post_date、post_date_gmt,这对于同一辆车上的每个帖子都是不同的。

有几种方法可以解决这个问题:

您可以进行分组,但您必须对不在分组依据的所有列进行aggregate function(最大值、最小值、平均值等)。

另一种方法是执行两个查询。第一个是您现在拥有的查询,但只有 original_id 在选择中。然后你有一个 original_ids 的集合,你可以在第一个查询中得到所有汽车的详细信息。

【讨论】:

【参考方案3】:

选择最新的。* 从详细信息中最新 在 post.id = latest.postid 上加入帖子 并且不存在 ( 从详细信息中选择 1 其中 latest.original_id = original_id 和 latest.post_modified

只是想法。

【讨论】:

【参考方案4】:

我可以在这里想到几个问题和解决方案。所以你从不同的网站得到提要??问,因为帖子作者在所有帖子中都是 1 !?

请对此进行一些澄清。而且您的 original_id 不是主键的一部分以防止重复条目吗??

【讨论】:

我想知道您如何获取信息/将信息输入到您的表格中,应该检查重复项,更新一行而不是重新插入一行!重复数据不是好的数据库设计!!【参考方案5】:

在发布新的重复记录时使用触发器删除每条旧记录怎么样?

CREATE TRIGGER REMOVE_OLD
ON CC_POST_DETAILS
BEFORE INSERT
AS
DECLARE @O_ID BIGINT(8), @MAKE VARCHAR(100), @MODEL VARCHAR(100)
BEGIN

SELECT @O_ID = INSERTED.ORIGINAL_ID FROM INSERTED
SELECT @MAKE = INSERTED.MAKE FROM INSERTED
SELECT @MODEL = INSERTED.MODEL FROM INSERTED

DELETE * FROM CC_POST_DETAILS
WHERE CC_POST_DETAILS.ORIGINAL_ID = @O_ID
AND CC_POST_DETAILS.MAKE = @MAKE
AND CC_POST_DETAILS.MODEL = @MODEL

END

我没有看到连接发生的确切位置,因此您也需要将其作为变量读取,以便更新其他表。如果您愿意,您可以在删除之前运行插入以将每个旧文件放入存档中。

【讨论】:

以上是关于连接两个表的工作查询是完美的,除了我无法摆脱重复项的主要内容,如果未能解决你的问题,请参考以下文章

从 MySQL 中具有不同列的表的多个连接结果中删除重复项

删除左表上的重复项,同时在右表SELECT JOIN上保留重复项

如何修改此工作 SQL SELECT/JOIN 查询以删除重复项?

SQL 查询有效地选择不完美的重复项

减少多值连接 SQL 查询中的重复记录

在不创建新表的情况下排除重复项的更好方法