【问题标题】:Filtering duplicate rows from MySQL table从 MySQL 表中过滤重复行
【发布时间】:2014-04-24 15:03:33
【问题描述】:

如果这已在其他地方得到回答,我会立即道歉。我似乎无法获得此版本的工作版本,并且我尝试了许多不同的东西,一些来自知识,另一些来自谷歌搜索。

我在我的 SQL 查询中使用 Haversine 公式来计算几家零售店的距离,以便将它们绘制在地图上。我得到了距离,什么不好,但是当我添加一个选项来过滤掉重复的或连锁的商店时,我遇到了问题。这些问题根据我尝试过的不同查询而有所不同,我想知道是否有人可以指出我哪里出错了,以便我可以从这次经历中学习。 :D

我尝试过的事情(注意:这些示例中的 lat/lon 是错误的 lat/lon,而我得到的 lat/lon 来自另一个 SQL 表):

SELECT store_id,col_a,col_b,col_c,store_name,store_number,street_address,apt_suite,city,state_id,zip_code,latitude,longitude,phone_number,phone_extension,fax_number,email_addr,location_direction,open_24_hr,website_url, (3959*acos(cos(radians(12.1234567)) * cos(radians(latitude)) * cos(radians(longitude)-radians(-45.678910.)) + sin(radians(12.1234567)) * sin(radians(latitude)))) AS distance FROM stores WHERE primary_provider_code = '01' OR secondary_provider_code = '01' OR tertiary_provider_code = '01' ORDER BY distance LIMIT 0 , 10

这将使我完成基础知识。获取最近的 10 家商店,按距离订购,并且只选择我想要的列。现在,当有人点击“过滤相同链”选项时,我尝试了以下操作:

SELECT store_id,col_a,col_b,col_c,store_name,store_number,street_address,apt_suite,city,state_id,zip_code,latitude,longitude,phone_number,phone_extension,fax_number,email_addr,location_direction,open_24_hr,website_url, (3959*acos(cos(radians(12.1234567)) * cos(radians(latitude)) * cos(radians(longitude)-radians(-45.678910.)) + sin(radians(12.1234567)) * sin(radians(latitude)))) AS distance FROM stores WHERE primary_provider_code = '01' OR secondary_provider_code = '01' OR tertiary_provider_code = '01' GROUP BY store_name ORDER BY distance LIMIT 0 , 10

这确实会渲染结果,但它实际上会过滤掉每个相同的链,而不仅仅是在显示一个之后。例如,如果我们有 Walgreens、Costco、Wal-Mart、Walgreens、Target 等……那么我只想显示第一个 Walgreens 并过滤掉第二个。谷歌搜索让我相信 GROUP BY 子句会起作用。它删除了所有沃尔格林。事实上,它删除了所有重复的行。

为了尝试,我还尝试了 GROUP BY store_name HAVING COUNT(*) = 1>,<,>=,<= 变体。

我不相信我可以做一个SELECT DISTINCT,因为其他列本身都是不同的,所以即使 store_name 可能有重复,我试图选择的所有其他行都是唯一的.此外,我已经尝试过并确认它不会过滤掉非唯一列。

提前感谢您的帮助。请注意,我也标记了 PHP,因为众所周知它可以与 SQL 交互,而我正在开发的平台是 PHP。

注意:我不是只寻找一家商店。我正在寻找所有商店,按距离排序,分组并过滤掉重复的商店。假设未经过滤的结果是

Wal-Mart
K-Mart
Wal-Mart
Walgreens
Costco
Sams Club
Wal-Mart
Costco
Walgreens

我要返回过滤后的结果:

Wal-Mart
K-Mart
Walgreens
Costco
Sams Club

【问题讨论】:

  • A GROUP BY 将删除重复项。问题是,如果您有(例如)10 家沃尔玛商店,并且您按连锁店名称进行分组,它将带回其中一家沃尔玛商店。哪一个(即所有不在 GROUP BY 中的字段的内容)是未定义的。

标签: php mysql sql


【解决方案1】:

一种解决方案:-

SELECT store_id,col_a,col_b,col_c,stores.store_name,store_number,street_address,apt_suite,city,state_id,zip_code,latitude,longitude,phone_number,phone_extension,fax_number,email_addr,location_direction,open_24_hr,website_url, sub1.distance AS distance 
FROM stores 
INNER JOIN
(
    SELECT store_name, MIN(3959*acos(cos(radians(12.1234567)) * cos(radians(latitude)) * cos(radians(longitude)-radians(-45.678910.)) + sin(radians(12.1234567)) * sin(radians(latitude)))) AS distance 
    FROM stores 
    WHERE primary_provider_code = '01' OR secondary_provider_code = '01' OR tertiary_provider_code = '01' 
    GROUP BY store_name 
) sub1
ON stores.store_name = sub1.store_name
AND (3959*acos(cos(radians(12.1234567)) * cos(radians(latitude)) * cos(radians(longitude)-radians(-45.678910.)) + sin(radians(12.1234567)) * sin(radians(latitude)))) = sub1.distance
WHERE primary_provider_code = '01' OR secondary_provider_code = '01' OR tertiary_provider_code = '01' 
ORDER BY distance LIMIT 0 , 10

这使用子查询来获取每个链的最近商店(因此在子查询中使用 MIN / GROUP BY),然后将其与 stores 表连接以获取最近商店的完整详细信息。

【讨论】:

  • 成功了!感谢您的帮助,这是一次很好的学习体验,重新编写它以输入我需要的额外部分。
【解决方案2】:

我在你的 SQL 中看不到错误,我在我的数据库中对其进行了测试并得到了正确的结果。

SELECT store_id,
col_a,
col_b,
col_c,
store_name,
store_number,
street_address,
apt_suite,
city,
state_id,
zip_code,
latitude,
longitude,
phone_number,
phone_extension,
fax_number,
email_addr,
location_direction,
open_24_hr,
website_url,
 (3959*acos(cos(radians(12.1234567)) * cos(radians(latitude)) * cos(radians(longitude)-radians(-45.678910.)) + sin(radians(12.1234567)) * sin(radians(latitude)))) AS distance 
    FROM stores 
    WHERE
      primary_provider_code = '01' OR 
      secondary_provider_code = '01' OR 
      tertiary_provider_code = '01' 
    GROUP BY GROUP BY store_name
    ORDER BY distance LIMIT 0 , 10

试试这个:

SELECT store_id,
col_a,
col_b,
col_c,
DISTINCT(store_name),
store_number,
street_address,
apt_suite,
city,
state_id,
zip_code,
latitude,
longitude,
phone_number,
phone_extension,
fax_number,
email_addr,
location_direction,
open_24_hr,
website_url,
 (3959*acos(cos(radians(12.1234567)) * cos(radians(latitude)) * cos(radians(longitude)-radians(-45.678910.)) + sin(radians(12.1234567)) * sin(radians(latitude)))) AS distance 
    FROM stores 
    WHERE
      primary_provider_code = '01' OR 
      secondary_provider_code = '01' OR 
      tertiary_provider_code = '01' 
    ORDER BY distance LIMIT 0 , 10

【讨论】:

  • 我不是只寻找一家商店。我正在寻找该地区的所有商店,过滤掉多余的商店。
  • 我也不能。但是,当我执行GROUP BY 子句时,我会丢失所有在数据库中有多余或重复项的商店。所以,既然我没有sql错误和不正确的结果,就想问问SO的人。
【解决方案3】:

如果您只是想要最近商店的不同商店名称,那么您可以在当前查询之上执行 DISTINCT,如下所示:

SELECT DISTINCT STORE_NAME
FROM
(SELECT
  STORE_ID,
  COL_A,
  COL_B,
  COL_C,
  STORE_NAME,
  STORE_NUMBER,
  STREET_ADDRESS,
  APT_SUITE,
  CITY,
  STATE_ID,
  ZIP_CODE,
  LATITUDE,
  LONGITUDE,
  PHONE_NUMBER,
  PHONE_EXTENSION,
  FAX_NUMBER,
  EMAIL_ADDR,
  LOCATION_DIRECTION,
  OPEN_24_HR,
  WEBSITE_URL,
  (3959     *ACOS(COS(RADIANS(12.1234567)) * COS(RADIANS(LATITUDE)) * COS(RADIANS(
  LONGITUDE)-RADIANS(-45.678910.)) + SIN(RADIANS(12.1234567)) * SIN(RADIANS(
  LATITUDE)))) AS DISTANCE
FROM
  STORES
WHERE
  PRIMARY_PROVIDER_CODE    = '01'
OR SECONDARY_PROVIDER_CODE = '01'
OR TERTIARY_PROVIDER_CODE  = '01'
ORDER BY
  DISTANCE LIMIT 0 ,
  10
) nearest_stores;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-10
    • 1970-01-01
    • 1970-01-01
    • 2015-11-20
    • 1970-01-01
    • 1970-01-01
    • 2011-07-18
    相关资源
    最近更新 更多