2014-11-24 75 views
0

我有一个表的数据,看起来像的最大如下:寻找另一个最大的查询

+--------+----------+------------+ 
| Client | Item No. | Serial No. | 
+--------+----------+------------+ 
| A  |  1 |   1 | 
| A  |  1 |   2 | 
| B  |  1 |   2 | 
| B  |  2 |   1 | 
| C  |  2 |   3 | 
| C  |  2 |   2 | 
| C  |  3 |   1 | 
| C  |  3 |   2 | 
| D  |  2 |   3 | 
| D  |  2 |   1 | 
| D  |  3 |   2 | 
| D  |  3 |   3 | 
| D  |  2 |   2 | 
| D  |  3 |   1 | 
+--------+----------+------------+ 

我正在寻找做的是找到为每个客户最高产品编号其次是最高序列号(以此顺序)。因此,对于上面的输出将是:

+--------+----------+------------+ 
| Client | Item No. | Serial No. | 
+--------+----------+------------+ 
| A  |  1 |   2 | 
| B  |  2 |   1 | 
| C  |  3 |   2 | 
| D  |  3 |   3 | 
+--------+----------+------------+ 

我想这需要一个嵌套MAX()语句,首先得到MAX(项目编号)为每一个客户,并为那些具有多那么得到MAX(序列号)什么是写这个查询的有效方法?

+0

其DBMS您使用的? MySQL的? – 2014-11-24 07:28:17

+0

我正在使用MS SQL 2008 – 2014-11-25 00:40:29

回答

1

也许这可以帮助:

SELECT t.client, 
     t.item, 
     MAX(t.serial) AS serial 
    FROM(SELECT client, 
       MAX(item) AS item 
     FROM your_table 
     GROUP 
      BY client 
    ) a 
    JOIN your_table t 
    ON a.client = t.client AND a.item = t.item 
GROUP 
    BY t.client, t.item 

如果你的DBMS支持窗口功能,另一种方法是:

SELECT client, item, serial 
    FROM(SELECT client, item, serial, 
       ROW_NUMBER() OVER (PARTITION BY client ORDER BY item DESC, serial DESC) rn 
     FROM your_table 
    ) 
WHERE rn = 1 
+0

伟大的解决方案,我想知道是否有像你提到的窗口功能可用的东西。在性能方面,Window函数能够更好地工作吗? – 2014-11-25 01:02:11

+0

除非查询优化器理解长版本并执行相同的操作,否则Windowing版本会更好。应该有一个EXPLAIN功能来比较查询计划。 – 2014-11-25 05:10:26

0

Postgres有,因为DISTINCT的真棒快捷

SELECT DISTINCT ON (Client) Client, Item, SerialNumber 
FROM some_table 
ORDER BY Item DESC, SerialNumber DESC -- DESC gets highest 

这只会为每个客户端抓取一条记录,而ORDER BY会确保它是您想要的。

我不知道如果任何其他DBMSs会这么容易做到这一点。

+0

是的,我希望这样的事情可以工作,但不是在MS SQL。最接近的方法是按照DirkNM的回答中所示的OVER子句进行操作。相同的想法,只返回您指定的行号,在这种情况下为1。 – 2014-11-25 02:02:05

0

这里是解决方案:

WITH CTE AS (
SELECT Client, MAX(Item_No) AS Item_No 
FROM YourTable 
GROUP BY Client) 

SELECT a.Client,b.Item_No,MAX(Serial_No) AS Serial_No 
FROM CTE a 
JOIN YourTable b ON a.Client = b.Client AND a.Item_No = b.Item_No 
GROUP BY a.Client,b.Item_No