2017-07-07 21 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