是否可以创建动态联合声明?

时间:2014-10-31 15:45:36

标签: mysql sql union

假设我有一张这样的桌子。我们可以称之为销售:

id  | purchaserID | item |      date   |
1   |      1      |  A1  |  2014-10-31 |
2   |      1      |  A2  |  2014-10-30 |
3   |      1      |  A3  |  2014-10-19 |
4   |      1      |  A2  |  2014-10-26 |
5   |      2      |  B1  |  2014-10-31 |
6   |      2      |  B2  |  2014-10-28 |
7   |      2      |  B3  |  2014-10-30 | 
8   |      1      |  C1  |  2014-10-27 |
9   |      2      |  B4  |  2014-10-01 |

我想要做的是获取每个购买者ID的最新购买日期N(我们将在此案例中为3)。我知道这是可能的,礼貌地提出了Stack上的其他问题。我知道一种方式(即使它不是最好的方式)是为每个购买者选择最新的3个日期并将它们合并在一起:

(SELECT * FROM sales WHERE purchaserID = 1 ORDER BY date DESC LIMIT 3)
UNION ALL
(SELECT * FROM sales WHERE purchaserID = 2 ORDER BY date DESC LIMIT 3)

我想知道的是 - 有没有办法让这个动态联合所有的购买者ID?如果ID 3购买,现在我必须重新创建我的查询以获得每个购买者的最新3个日期。

我已经为你制作了SQL Fiddle

1 个答案:

答案 0 :(得分:0)

我认为无需联合就能满足您的需求:

CREATE TABLE #Purchases (
id  int, 
purchaserID int, 
item varchar(2),      
date datetime,
)
INSERT INTO #Purchases VALUES
(1   ,      1      ,  'A1'  ,  '2014-10-31') ,
(2   ,      1      ,  'A2'  ,  '2014-10-30') ,
(3   ,      1      ,  'A3'  ,  '2014-10-19') ,
(4   ,      1      ,  'A2'  ,  '2014-10-26') ,
(5   ,      2      ,  'B1'  ,  '2014-10-31') ,
(6   ,      2      ,  'B2'  ,  '2014-10-28') ,
(7   ,      2      ,  'B3'  ,  '2014-10-30'), 
(8   ,      1      ,  'C1'  ,  '2014-10-27') ,
(9   ,      2      ,  'B4'  ,  '2014-10-01') 

SELECT *
FROM #purchases a
WHERE ((
  SELECT count(*) FROM #Purchases as b WHERE 
    b.date > a.date AND
    b.purchaserID = a.purchaserID
) + 1) <= 3
order by purchaserId, date desc

DROP TABLE #Purchases

返回:

id  purchaserID item    date
1   1   A1  2014-10-31 00:00:00.000
2   1   A2  2014-10-30 00:00:00.000
8   1   C1  2014-10-27 00:00:00.000
5   2   B1  2014-10-31 00:00:00.000
7   2   B3  2014-10-30 00:00:00.000
6   2   B2  2014-10-28 00:00:00.000

这句话虽然是O(n ^ 2)。希望这个数据集不是特别大。