2013-03-23 4 views
0

Этого запрос возвращает данные, которые я требую данных конкретной traceid значения (50 в этом примере, который является ключом, который существует в обеих таблицах, tblResults и tblTraces:MySQL. Присоедините эти два запроса вместе с соединением или подзапросом?

SELECT count(changed) 
FROM (
    SELECT changed 
    FROM tblResults 
    WHERE traceid = 50 
    AND changed = 1 
    ORDER BY resultid DESC 
    LIMIT 0,20 
) as R 

Я хочу, чтобы запустить этот выше запрос к почти каждый traceid (так, выбирая 20 строк для каждого traceid, а не только traceid 50, так что 3 traceid будет означать 60 строк) Это просто выберите ниже получает необходимые traceid значения:.

SELECT `traceid` FROM `tblTraces` WHERE `enabled` = 1 

Как я могу «склеить» два вопроса вместе?

Так что я себе представить запрос вроде следующего, за исключением того, что не будет работать, потому что подзапрос возвращает несколько строк (которые я хочу):

SELECT count(changed) 
FROM (
    SELECT changed 
    FROM tblResults 
    WHERE traceid = (
        SELECT `traceid` FROM `tblTraces` WHERE `enabled` = 1 
        ) 
    AND changed = 1 
    ORDER BY resultid DESC 
    LIMIT 0,20 
) as R 
+0

Покажите нам выход 'SHOW CREATE TABLE tblResults,' –

+0

В таблице 'tblTraces' различны' traceid'? – Justin

+0

@ Justin да они – jwbensley

ответ

0

В MySQL нет простой способ сделать это. В других базах данных вы просто используете row_number(), но он недоступен.

Вот один подход, предполагая, что resultId уникален по каждой строке:

select t.traceId, count(changed) 
from (select traceid, ResultId, changed, 
      (select count(*) from tblResults r2 where r2.traceId = r.traceId and r2.ResultId >= r.ResultId and r2.changed = 1) as seqnum 
     from tblResults r join 
      tblTraces t 
      on r.TraceId = t.TraceId and t.enabled = 1 
     where r.changed = 1 
    ) t 
where seqnum <= 20 
group by traceId 

Если вы не хотите этого, traceid и просто хотите общий счет, а затем удалить group by и изменить select к count(changed) ,

+0

Фу! Это был лапша-пекарь! Таким образом, это работает отлично. Мне просто пришлось удалить 'и r2.changed = 1', я вручную проверил вручную ответы, которые он отлично работает. Теперь мне нужно сделать кофе и провести некоторое время, полностью понимая этот ответ, его большой. Благодаря! – jwbensley

0

Вы можете просто сделать внутреннее соединение, как так

select count(traceid) 
    from tblResults a inner join tblTraces b on a.traceid = b.traceid 
    and b.enabled = 1 
    and a.changed = 1 

Или я пропустил что-то еще здесь?

+1

«LIMIT 20» за след усложняет ситуацию. –

1

Вот еще один способ сделать это. Я адаптировал Bill Karwin's example. См. Его сообщение для более подробного объяснения.

 
SELECT x.traceId, COUNT(*) 
FROM (
    SELECT a.* 
    FROM tblResults a 
    -- Be sure not to exclude tblResults which are the only record in the trace 
    LEFT OUTER JOIN tblResults b 
     -- We're going to count how many rows came "before" this one 
     ON a.changed = b.changed 
    AND a.traceId = b.traceId 
    AND a.resultId < b.resultId 
    WHERE a.changed = 1 
    AND a.traceId IN (SELECT traceId FROM tblTraces WHERE enabled = 1) 
    GROUP BY a.resultId 
    HAVING COUNT(*) < 20  -- Eliminate rows ranked higher than 20 
    ORDER BY b.resultId DESC -- when we rank them by resultid 
) x GROUP BY x.traceId 

не Внешний запрос только для проверки того, что каждый traceid не содержит более 20 отдельных записей, а внутренний запрос результирующий набор вы на самом деле заинтересованы в.

+0

Вам нужно 'LEAST()', а не 'MIN()' там. Но у меня была такая же мысль. –

1

Хотя я не удовлетворен этим ответом, это, вероятно, самый простой для маленьких таблиц:

SELECT tblTraces.traceid, LEAST(20, SUM(tblResults.changed)) 
FROM tblTraces 
    LEFT JOIN tblResults 
    ON tblTraces.traceid = tblResults.traceid 
WHERE tblTraces.enabled = 1 
AND tblResults.traceid.changed = 1 
GROUP BY tblTraces.traceid 

Ограничение на колонке действительно усложняет присоединение.

1

Непонятно, требуется ли вам количество этих результатов (ограничено до 20 на трассировку) или фактических результатов. Только для подсчета, есть простой способ:

SELECT t.traceid, 
     LEAST(COUNT(*),20) AS cnt 
    FROM tblTraces AS t 
    JOIN tblResults AS r 
     ON r.traceid = t.traceid 
    WHERE t.enabled = 1 
    AND r.changed = 1 
    GROUP BY t.traceid ; 

тест в SQL-Fiddle

Смежные вопросы