2013-03-23 67 views
0

此查詢返回我需要給定具體traceid值(50在本例中,這是存在兩個表中,tblResultstblTraces一密鑰對數據: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(因此,選擇每個traceid 20行,而不僅僅是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;' – 2013-03-23 20:41:30

+0

在表'tblTraces'是不同的'traceid'? – Justin 2013-03-23 20:41:50

+0

@Justin是的,他們是 – jwbensley 2013-03-23 20:49:22

回答

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,改變selectcount(changed)

+0

唷!那是相當的麪條麪包師!所以,這是完美的。我只需要刪除'和r2.changed = 1',我手動檢查了它的完美工作。現在我需要製作一杯咖啡,花一些時間充分理解這個答案,它很棒。謝謝! – jwbensley 2013-03-23 21:21:04

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'使事情複雜化。 – 2013-03-23 20:45:40

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

您需要'最少()',而不是'MIN()'。但我有同樣的想法。 – 2013-03-23 21:01:12

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