2017-07-07 30 views
2

我试图使用Max(),子查询和连接,但我的知识是有限的,我不知道如何组织它们。我愿意只使用几个嵌套的select语句,知道它可能是资源密集型的,但我无法实现它。如何在一组行中返回多个值。

我需要返回任何空值以及每个位置的最高ConfigID。

TABLE 
ID  Location  ConfigID 
1  AA   NULL 
2  AA   2 
3  AA   1 
4  BB   5 
5  BB   4 
6  BB   3 
7  CC   NULL 
8  CC   6 

我想看到的结果:

ID  Location  ConfigID 
1  AA   NULL 
2  AA   2 
4  BB   5 
7  CC   NULL 
8  CC   6 

我曾尝试:

select ID, Location, ConfigID 
from Table 
where ConfigID is null 
     or configID = (select ConfigID 
        from table 
        where Location in (select distinct Location 
             from Table 
             order by ConfigID desc 
             ) 
        ) 

SQL服务器不一样,因为我不能在一个子查询,除非有一个ORDER BY顶部使用。现在我又看了一遍,我不认为顺序是在正确的子查询中。它尽可能接近我所能得到的。当我看到Select Max from each subset时,我很有希望,但我认为这是一个死胡同。另外,我不相信自联接会起作用,因为我将自联接的数据全部在一列中。

回答

1

你快到了。是的,你需要使用TOP 1,那有什么问题?

试试这个:

SELECT ID, Location, ConfigID 
FROM myTable t1 
WHERE ConfigID IS NULL 
    OR ID = (SELECT TOP 1 ID 
      FROM myTable t2 
      WHERE t2.Location = t1.Location 
      ORDER BY ConfigID DESC) 

这里是一个fiddle

+0

我必须说服自己到不使用前出于某种原因。这很好。 – JuuB406

+0

也许你没有把它放在正确的地方,因为你有两个子查询。你也可以用'union'来做,就像你在其他答案中看到的一样,但这个答案是最简单的,也可能是最快的。 –

1

你最好有NULL小号单独的查询和最高ConfigID,然后UNION它们,然后ORDER BY ID

WITH cte 
AS 
(
    SELECT ROW_NUMBER() OVER(PARTITION BY Location ORDER BY Location, ConfigId DESC) AS rn, * 
    FROM [Table] 
    WHERE ConfigID IS NOT NULL 
    UNION ALL 
    SELECT 1, ID, Location, ConfigID 
    FROM [Table] 
    WHERE ConfigID IS NULL 
) 
SELECT ID, Location, ConfigID FROM cte 
WHERE rn = 1 
ORDER BY ID 

链接SQL Fiddle

+0

@RacilHilan感谢您的反馈。更正了SQL查询。 –

-1
SELECT DISTINCT ID, Location, ConfigID 
FROM Table 
WHERE ConfigID IS NULL 
     OR ID = (SELECT ID FROM Table AS t2 
         WHERE t2.Location = Table.Location 
              ORDER BY ConfigID DESC LIMIT 1) 
ORDER BY Location 
+0

问题是针对SQL Server,而不是MySQL哪些是您的查询将工作。 SQL Server中没有“LIMIT”。 –

1

我会用一个查询来获取NULL项,然后用PARTITION BY第二查询来获取顶级一行ConfigID来为每个位置。最后做一个UNION ALL得到最终的结果集和排序。这里是小提琴:http://sqlfiddle.com/#!6/dab30/2/0。查询低于:

SELECT 
    * 
FROM 
(
    -- This query gets the NULL ConfigID entries. 
    SELECT 
     TestTable.ID, 
     TestTable.[Location], 
     TestTable.ConfigID 
    FROM 
     TestTable 
    WHERE 
     TestTable.ConfigID IS NULL 

    UNION ALL 

    -- This query utilizes the PARTITION BY to get the max ConfigID for each group. 
    SELECT 
     TestTablePartitioned.ID, 
     TestTablePartitioned.[Location], 
     TestTablePartitioned.ConfigID 
    FROM 
    (
     SELECT 
      ROW_NUMBER() OVER 
      (
       PARTITION BY 
        [Location] -- The column to group the partition by. 
       ORDER BY 
        ConfigID DESC -- The column used to determine partition order. 
      ) AS PartitionIndex, 
      TestTable.ID, 
      TestTable.[Location], 
      TestTable.ConfigID 
     FROM 
      TestTable 
     WHERE 
      TestTable.ConfigID IS NOT NULL 
    ) AS TestTablePartitioned 
    WHERE 
     TestTablePartitioned.PartitionIndex = 1 -- Gets the top entry (max ConfigID) for each location. 
) AS TestTableUnion 
ORDER BY 
    TestTableUnion.[Location], 
    TestTableUnion.ConfigID 
1
SELECT * 
FROM Table D WHERE 
    ConfigID = (SELECT MAX(ConfigID) FROM Table 
    WHERE Location=D.Location) 
     Union 
Select * From Table 
    Where ConfigID Is NULL 
order by Location 
+0

我不知道工会。一般来说,更好地使用资源来建立工会或子查询?或者,因为它们都在运行两个查询,它本质上是一样的吗? – JuuB406

1
-- ID  Location  ConfigID 

WITH CTE_TMP (ID, LOCATION, CONFIGID) 
AS 
(
SELECT 1 ID, 'AA' LOCATION, NULL CONFIGID 
UNION 
SELECT 2, 'AA', 2 
UNION 
SELECT 3, 'AA', 1 
UNION 
SELECT 4, 'BB', 5 
UNION 
SELECT 5, 'BB', 4 
UNION 
SELECT 6, 'BB', 3 
UNION 
SELECT 7, 'CC', NULL 
UNION 
SELECT 8, 'CC', 6 
) 
SELECT DISTINCT ID, LOCATION, CONFIGID FROM CTE_TMP WHERE CONFIGID IS NULL 
UNION 
SELECT A.ID, A.LOCATION, B.CONFIGID 
FROM CTE_TMP A 
    JOIN (SELECT LOCATION, MAX(CONFIGID) CONFIGID FROM CTE_TMP 
     GROUP BY LOCATION) B ON A.LOCATION = B.LOCATION AND A.CONFIGID = B.CONFIGID 
相关问题