Mysql

對於欄位 A 中的每個值,選擇欄位 B 中具有某些特殊值的行,同時遵守進一步的標準

  • October 3, 2018

**免責聲明:*雖然我的問題的基礎- 每組最大的*問題 - 之前已經被問過並回答了很多次,但由於我必須申請額外的條件,我面臨著一個看似困難的問題。

如果我真的錯過了某個地方給出的確切問題的答案,我很抱歉。我搜尋、閱讀、嘗試了很多,我已經花了半天時間在這上面。


我試圖描述標題中的抽象問題:對於任何其他欄位 A 值,獲取具有某些特殊欄位 B 值的行,同時尊重進一步的條件。

現在,我的具體問題如下……我有下表:

CREATE TABLE IF NOT EXISTS `mdl_datasets` (
 `id` bigint(10) NOT NULL AUTO_INCREMENT,
 `cmid` bigint(10) NOT NULL DEFAULT '0',
 `userid` bigint(10) NOT NULL DEFAULT '0',
 `timecreated` bigint(10) NOT NULL DEFAULT '0',
 PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;

對於一個特定****模組(即userid)中的每個****使用者(即 後半部分讓人很難。cmid``timecreated``timecreated

如果不使用至少三個(子)查詢,我看不出我怎麼能做到這一點,即使那樣我也無法讓它在任何情況下正常工作。

到目前為止,我只設法讓它部分工作,例如,僅適用於至少有兩行的使用者。這當然是錯誤的。如果有一個使用者只有一行,它的timecreated值是正確的,那麼我想得到這一行作為結果。timecreated對於任何其他使用者,我想獲得低於給定最大日期(作為 Unix 紀元時間戳)的最大值的一行。

還有什麼我應該提到的嗎?告訴我。

我認為這是完全相同的情況,max-per-group但有一些擴展條件,可以通過單個子查詢來解決:

SELECT IF( b.id IS NULL, NULL, a.id ) AS id -- an opposite to COALESCE()
    , a.cmid
    , a.userid
    , b.maxts -- can be NULL 
 FROM table AS a 
 LEFT JOIN ( SELECT id -- if you need no rows for users have no rows before 
                       -- the given timestamp replace the LEFT JOIN 
                       -- by plain JOIN
                  , cmid
                  , userid
                  , MAX(timecreated) AS maxts
               FROM table 
              WHERE cmid = given_cmid
                AND timecreated < given_timecreated -- additional condition
              GROUP BY userid
           ) AS b ON b.userid = a.userid
                 AND b.cmid   = a.cmid
                 AND b.maxts  = a.timecreated
 WHERE a.cmid = given_cmid
;

此查詢為userid表中的每個生成結果,包括那些在之前沒有行given_timecreated但帶有的行maxtsidcmid設置為NULL.

這裡WHERE cmid = given_cmid使用了兩次條件來減小子查詢結果的大小。

當然,您需要一個索引(cmid, userid, timecreated)才能獲得可接受的性能。索引中列出的順序列可以根據您擁有的特定數據而有所不同。

引用自:https://dba.stackexchange.com/questions/219015