客户端可以拥有多个设备(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完全没有效果一样。
答案 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