2011-08-12 3 views
0

나는 다음과 같은 쿼리가 :부분적으로 중복 데이터에서 선호하는 행을 선택

select 
    mb.id as meter_id 
    ,ds.mydate as mydate 
    ,mb.name as metergroup 
    ,sum(ms.stand) as measured_cum_value 
    ,me.name as energy_medium 
    ,e.name as unit_of_measure 
    ,min(ms.source) as source 
    ,count(*) as debugcount 
FROM datumselect ds       <<-- mem table with dates to query. 
INNER JOIN metergroup mb ON (mb.building_id = 1) 
INNER JOIN meter m ON (m.metergroup_id = mb.id) <<-- meters are grouped 
INNER JOIN medium me ON (me.id = mb.medium_id) <<-- lookuptables for normalization 
INNER JOIN unit e ON (e.id = mb.unit_id)   <<-- ditto 
INNER JOIN meterstand ms ON (ms.meter_id = m.id AND ms.mydate = ds.mydate) 
group by ds.mydate, mb.id, ms.source <<-- this is prob. broken. 
having source = MIN(ms.source) <<-- this `having` does not work ! 
ORDER BY mb.id, ds.mydate 

나는 다음과 같은 테이블에서 선택 해요 :

CREATE TABLE meterstand(
    id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, 
    meter_id INT(11) UNSIGNED NOT NULL, 
    mydate DATETIME NOT NULL, 
    stand DECIMAL(16, 5) NOT NULL, 
    source ENUM('calculated', 'read', 'manual') NOT NULL DEFAULT 'read', 
    PRIMARY KEY (id), 
    INDEX FK_meterstand_meter_id (meter_id), 
    UNIQUE INDEX UK_meterstand (datum, meter_id, bron), 
    CONSTRAINT FK_meterstand_meter_id FOREIGN KEY (meter_id) 
    REFERENCES vaanstermeters.meter (id) ON DELETE RESTRICT ON UPDATE CASCADE 
) 
ENGINE = INNODB 
AUTO_INCREMENT = 181 
AVG_ROW_LENGTH = 105 
CHARACTER SET latin1 
COLLATE latin1_swedish_ci; 

아래의 데이터가 될 것 주어지는 간단한 쿼리를 :

SELECT 
    meter_id 
    , mydate 
    , sum(stand) 
    , count(*) as debugcount 
FROM meterstand 
WHERE mydate IN (list_of_dates_im_interested_in) 
GROUP BY meter_id, my_date 
HAVING the_best(source) 

항상 일을해야 debugcount 현재 데이터를 감안할 때,하지만 여러 미터가있는 경우 위의 쿼리 debugcount의 그룹에 속한 그룹의 수는 미터의 수 여야합니다.

다른 소스에서 값을 선택할 수 있습니다.
- manual 출처 : 이것은 황금색입니다.
- read 데이터 소스의 소스, 건물의 미터, 어딘가에 있습니다.
- calculated 누락 된 데이터를 보완하기 위해 보간 된 데이터.

동일한 meter_id + mydate을 갖는 단일 데이터 포인트는 여러 소스를 가질 수 있습니다.
쿼리는 manual의 소스를 read 이상으로 지정하고 다른 데이터를 사용할 수없는 경우 calculated 데이터 만 선택해야합니다.

id meter_id mydate stand  source 
------------------------------------------------------ 
179 6 1-12-2010 94,75886 calculated 
180 7 1-12-2010 256,02618 calculated 
164 7 1-1-2011 285,41800 manual <<--- Query should only consider this row. 
183 7 1-1-2011 0,00000  read <<-- and forget about this one 

최고의 데이터 포인트를 선택하는 데 사용할 수있는 적절한 쿼리 구문은 무엇입니까 : 여기

meterstand에있는 데이터의 샘플입니다?

답변

1

MySQL은 열거 형의 정렬 순서를 정의에 나열된 순서로 정의합니다. 당신은 그들이 표시되어있는 역으로 순서를 정의한 것을 감안할 때, 나는 예상대로 다음은 (비록에 대해 테스트 할 인스턴스)를 작동하지 않습니다 믿습니다

SELECT * 
FROM meterstand as a 
JOIN (SELECT meter_id, mydate, MAX(source) as source 
     FROM meterstand 
     GROUP BY meter_id, mydate) as b 
ON b.meter_id = a.meter_id 
AND b.mydate = a.mydate 
AND b.source = a.source 

이 (가정하면 [meter_id, MyDate가 , 출처] 물론 독특합니다.

enum이 문자열 값에 따라 정렬되는 버그가있는 것처럼 보입니다. 문자열을 사용하면 전혀 도움이되지 않습니다. 이 문턱 존재 (또는 사용 순서를 통해 좀 더 컨트롤을 원하는) 경우
, 당신은 테이블을 정의 할 수 있습니다 :

Meter_Reading_Type 
======================== 
Id Description Priority 
1 Manual  10 
2 Calculated 30 
3 Read   20 

그런 다음 FK로 참조 ​​및 정렬 (분) 우선 순위입니다.

+0

너무 단순하기 때문에 마음이 복잡해지기 시작했습니다. 감사. – Johan

관련 문제