请高效查询

时间:2010-12-21 23:29:38

标签: sql sql-server-2005 performance group-by

我希望有效查询从我的表中获取一些行。

这是我认为我桌子的最佳展示。

-Somedate is not duplicated - it is date of modifiedon
-a,b,c are parent ids, let say countryCode
-1,2,3,4 are subparent, let say citycode
-guids are id of rows
-true, false are values of rows  - one can name this column - freshAir


a 1 GUID somedate true
a 1 GUID somedate true
a 2 GUID somedate false
a 2 GUID somedate false
b 3 GUID somedate false
b 3 GUID somedate false
b 3 GUID somedate false
b 4 GUID somedate false
c 5 GUID somedate true
c 6 GUID somedate true
c 6 GUID somedate false
c 6 GUID somedate false
c 7 GUID somedate false

我想要按国家/地区代码和城市代码分组的最新行MAX(modifiedon),在这些组中我需要具有其他值的元素(true,false)。

结果我想:

a 1 GUID somedate true
a 2 GUID somedate false
c 5 GUID somedate true
c 6 GUID somedate false
c 7 GUID somedate false

看看结果我不想让记录带有“b”,因为所有行都有相同的值(false)。

编辑:

IDResearch CountryCode  CityCode  ReligionCode Date
1          FR           PAR       CAT           11-11-2000
2          FR           PAR       CAT           11-11-2002
3          FR           STR       ISL           09-12-1975
4          FR           STR       ISL           09-12-1995
5          GR           ATE       PRA           09-12-1976
6          GR           ATE       PRA           09-12-1986
7          GR           SAL       PRA           09-12-1986
8          ES           BCN       ATH           01-07-2001
9          ES           BCN       ATH           01-08-2001
10         ES           MAD       CAT           01-07-2008
11         ES           VAL       CAT           01-07-2009

我想从表中研究来自主导宗教不同的国家的行。所以在巴黎的法国占主导地位的是天主教,但在斯特拉斯堡是伊斯兰教,所以我想要来自这个国家的最新记录:

 2          FR           PAR       CAT           11-11-2002
 4          FR           STR       ISL           09-12-1995

接下来,所有城市的希腊都是相同的地区,所以我不想要这个国家的记录。

在西班牙城市,主导宗教的情况并不相同,所以我也想要来自西班牙的记录

  9          ES           BCN       ATH           01-08-2001
  10         ES           MAD       CAT           01-07-2008
  11         ES           VAL       CAT           01-07-2009

我希望这会有所帮助并引入更多清晰度。

4 个答案:

答案 0 :(得分:1)

Mark Byers和Dog Ears解决方案的唯一问题是他们取消了所有行中只有相同宗教代码的国家。现在考虑一下情景:

5          GR           ATE       PRA           09-12-1976
6          GR           ATE       PRA           09-12-1986
7          GR           SAL       PRA           09-12-1986
8          GR           SAL       ISL           11-01-1985

从逻辑上讲,我们仍然应该省略GR,因为最终的研究显示了它的所有PRA!这些疑问并没有涵盖我害怕的那种情况。 如果在您的情况下这是一个问题,我的解决方案是:

WITH LastResearch AS(
    SELECT R2.IDResearch,R2.countryCode,R2.CityCode,R2.ReligionCode,R2.Date FROM
    ((select countryCode,CityCode,max(Date) Date
        from researches R1
        Group by countryCode,CityCode)A
    INNER JOIN 
    researches R2
    ON (A.countryCode=R2.countryCode AND A.CityCode=R2.CityCode AND A.Date=R2.Date))),
FilteredCountry AS(
    SELECT countryCode FROM LastResearch
    GROUP BY countryCode
    HAVING COUNT(DISTINCT ReligionCode)>1
)
SELECT * FROM LastResearch
WHERE countryCode IN (SELECT countryCode FROM FilteredCountry)

答案 1 :(得分:0)

我认为你正在寻找类似(postgreSQL)的东西:

SELECT *
FROM myTable
WHERE (countrycode, citycode, modifiedon) IN (SELECT countrycode, citycode, MAX(modifiedon) FROM myTable)

答案 2 :(得分:0)

试试这个:

WITH countries AS
(
    SELECT countryCode
    FROM researches T1
    GROUP BY CountryCode
    HAVING COUNT(DISTINCT ReligionCode) > 1
),
max_rows AS
(
    SELECT researches.countryCode, cityCode, MAX(Date) AS Date
    FROM countries
    JOIN researches
    ON countries.countryCode = researches.countryCode
    GROUP BY researches.countryCode, cityCode
)
SELECT T2.*
FROM max_rows AS T1
JOIN researches AS T2
ON T1.cityCode = T2.cityCode
AND T1.countryCode = T2.countryCode
AND T1.Date = T2.Date

答案 3 :(得分:0)

或者,您可以使用Rank() function

with countries as
(   select countryCode
    from researches r
    Group by CountryCode
    having COUNT(distinct REligionCode) > 1
),
partitioned as
(
    select   r1.*
            ,rank() over (partition by r1.countryCode, r1.cityCode order by r1.Date desc) as position
    from researches r1 
    join countries c on r1.CountryCode = c.CountryCode
)
select * from partitioned where position = 1 

我不确定哪个选项效果最好..也许您可以告诉我们?