【问题标题】:SQL Server: SELECT row once only where two values are the same [duplicate]SQL Server:仅在两个值相同的情况下选择行一次[重复]
【发布时间】:2018-07-27 11:53:40
【问题描述】:

我正在开发由IP2Location 提供的OpenSource免费数据库,其中列出了来自互联网的大量 IP 地址。

您可以从here下载。

我的主要兴趣不是 IP 地址:我希望每个国家/地区的每个城市都有 1 个地理坐标。

我现在的查询返回双倍:

WITH cte AS
(   
    -- Let's pass rows that have the same latitude and longitude
    SELECT *, ROW_NUMBER() OVER (PARTITION BY latitude, longitude 
                            ORDER BY latitude, longitude) AS rn
    FROM ip2location_db11
    -- Avoid rows without city name
    where city_name != '-'          
)

SELECT
-- These are the only columns I'm interested in from the whole ip2location_db11 database
ROW_NUMBER() OVER (ORDER BY country_code desc,city_name desc) as countdown_order,
latitude,longitude,city_name,country_code
FROM cte
-- Let's take the first row where latitude and longitude are the same
WHERE rn = 1
-- I want to order results by city name
order by countdown_order desc

这很烦人:

每个城市有一个纬度经度的一行就可以了:我只想在地图上放一个大头针

【问题讨论】:

  • 只需使用 row_number() over(partition by city_name order by countdown_order) 然后每个城市只会得到 1 行 - 在当前查询的外部选择中执行

标签: sql-server select subquery common-table-expression


【解决方案1】:

编辑如果您可以在不同的 country_code 中拥有相同的城市,您只需将其写入分区 by 即可。否则应该是这样的:

WITH cte AS
(   
    -- Let's pass rows that have the same latitude and longitude
    SELECT *, ROW_NUMBER() OVER (PARTITION BY latitude, longitude 
                            ORDER BY latitude, longitude) AS rn
    FROM ip2location_db11
    -- Avoid rows without city name
    where city_name != '-'          
)
,columnsneeded as (

SELECT
-- These are the only columns I'm interested in from the whole ip2location_db11 database
ROW_NUMBER() OVER (ORDER BY country_code desc,city_name desc) as countdown_order,
latitude,longitude,city_name,country_code
FROM cte
-- Let's take the first row where latitude and longitude are the same
WHERE rn = 1
)

Select countdown_order,latitude,longtitude,city_name,country_code 
from(
Select *,ROW_NUMBER() over(partition by city_name order by countdown_order) as rn1 from columnsneeded
)x where rn1 = 1
-- I want to order results by city name
order by countdown_order desc

【讨论】:

  • 我特别喜欢您的查询,因为它完全按照我的意愿完成了工作。执行只需 9 秒。谢谢
【解决方案2】:

我不知道,您的第一列 (countdown_order) 是否有任何意义,或者只是该行的唯一标识符...

无论如何,如果您只想拥有一个带有一对坐标的城市/国家,您可能应该使用 GROUP BYAVG() 聚合函数来平均给定城市的坐标...

SELECT AVG(latitude) AS latitude, AVG(longitude) AS longitude, city_name, country_code
FROM ip2location_db11
GROUP BY country_code, city_name
ORDER BY country_code, city_name

【讨论】:

  • 即使您的查询不是我想要的,我也非常感谢AVG()。我认为即使查询执行速度很慢(> 40 秒),这也是一个天才的想法。谢谢你,你今天教我一些东西
【解决方案3】:

您需要做的就是使用按城市分区的ROW_NUMBER(并按任何东西排序:))并在外部查询中仅采用等于一的那些(您必须环绕您的查询)。试试这个:

SELECT countdown_order,latitude,longitude,city_name,country_code FROM (
    SELECT
    -- These are the only columns I'm interested in from the whole ip2location_db11 database
    ROW_NUMBER() OVER (ORDER BY country_code desc,city_name desc) as countdown_order,
    ROW_NUMBER() OVER (PARTITION BY city_name ORDER BY latitude) rnTofilter,
    latitude,longitude,city_name,country_code
    FROM cte
    -- Let's take the first row where latitude and longitude are the same
    WHERE rn = 1
    -- I want to order results by city name
) a WHERE rnToFilter = 1
order by countdown_order desc

【讨论】:

  • 嗨@Michal,查询返回我Msg 208, Level 16, State 1, Line 1 Invalid object name 'cte'.。如果我然后将FROM cte 更改为FROM ip2location_db11 它返回我Msg 207, Level 16, State 1, Line 9 Invalid column name 'rn'. 从那里我不知道要更改什么。但我知道你想做什么。感谢您的帮助
猜你喜欢
  • 2012-12-20
  • 1970-01-01
  • 1970-01-01
  • 2019-07-04
  • 1970-01-01
  • 1970-01-01
  • 2019-12-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多