仅选择第一个和最后一个结果

时间:2015-12-14 16:14:42

标签: mysql sql

客户端可以拥有多个设备(SerialNo)。每台设备都有成本,每个月都会记录每台设备的数据。我试图根据查询的时间段仅选择每个设备的第一个和最后一个结果。

"
SELECT i.SerialNo
     , p.Name
     , c.Cost
     , ci.DataDate
     , ci.Data
     ,
  FROM install i
  JOIN product p USING (ProductId)
  JOIN counter c USING (InstallId)
  JOIN counter_item ci USING (CounterId)
 WHERE i.ClientId LIKE $clientId
   AND MONTH(ci.DataDate) BETWEEN $mStart AND $mEnd
 ";

此选择有效,但它会检索开始日期和结束日期之间的所有记录。

我试过,得到最好的结果并且认为我会使用A UNION ALL与底部结果(ci.DataDate ASC)结合,但它不起作用。我只是第一次遇到记录。

GROUP BY i.SerialNo
ORDER BY ci.DataDate DESC

就像ORDER BY完全没有效果一样。

3 个答案:

答案 0 :(得分:1)

在counter_item中,您可以找到时间范围内每个CounterId的第一个和最后一个DataDate。因此,首先通过聚合找到这些并使用此信息以加入所需的记录:

SELECT i.SerialNo,
       p.Name,
       c.Cost,
       ci.DataDate,
       ci.Data
FROM install i
JOIN product p ON p.ProductId = i.ProductId
JOIN counter c ON c.InstallId = i.InstallId
JOIN 
(
  SELECT CounterId, MIN(DataDate) AS MinDate, MAX(DataDate) AS MaxDate
  FROM counter_item
  WHERE MONTH(DataDate) BETWEEN $mStart AND $mEnd
  GROUP BY CounterId
) minmax ON minmax.CounterId = c.CounterId
JOIN counter_item ci ON ci.CounterId = minmax.CounterId
                     AND ci.DataDate IN (minmax.MinDate, minmax.MaxDate)
WHERE i.ClientId LIKE $clientId
ORDER BY i.SerialNo, ci.DataDate

答案 1 :(得分:0)

你可以用下一个方式来做,这里只是关于如何做到这一点的一般概念:

select * from table
where 
    ([row] = (select max([row]) from table ) or 
    [Date] = (select min([row]) from table ))

答案 2 :(得分:-1)

您也可以使用交叉申请。像这样的,未经测试的粗糙样本:

SELECT i.SerialNo,
    p.Name,
    c.Cost,
    MIN(ci.DataDate) as MinDate,
    b.MaxDate,
    ci.Data,
 FROM install i
 CROSS APPLY (SELECT  
    MAX(ci.DataDate) as MaxDate
 FROM install     
 JOIN counter_item ci USING (CounterId)
 WHERE i.ClientId LIKE $clientId
 AND MONTH(ci.DataDate) BETWEEN $mStart AND $mEnd) b
 WHERE i.ClientId LIKE $clientId
 AND MONTH(ci.DataDate) BETWEEN $mStart AND $mEnd
 GROUP BY i.SerialNo
 ORDER BY ci.DataDate DESC