簡體   English   中英

SQL邏輯:兩個表(分組依據?)

[英]SQL logic: two tables (group by?)

我有兩個表,一個電影表(mt,主表),和一個列出這些電影可用的表(st,第二個表)。 對於每個mt記錄,都有多個st記錄。 我需要一個查詢,該查詢將加入記錄,並允許我在兩個表上運行查詢。 我目前使用這樣的內部聯接:

SELECT * FROM
(
    SELECT ROW_NUMBER() OVER(ORDER BY " + orderField + @") AS RowNum,
           mt.ID AS mt_ID,
           mt.title AS mt_title,
           [...]
           st.ID AS st_ID,
           st.title AS st_title,
           [...]
    FROM mt AS mt 
    st AS st
    INNER JOIN sttable AS st on mt.ID =st.ID
    WHERE st.title=@variable <> 0 AND mt.title = @variable
)    
    as DerivedTableName
    WHERE RowNum between 
    ((@pageIndex - 1) * @pageSize + 1) and @pageIndex*@pageSize

問題是我需要使用RowNum和pageIndex遍歷mt,並且查詢為每部電影返回多個記錄(例如,如果某部電影有8條記錄,則為8條,而不是1條)記錄返回)。 我曾嘗試使用GROUP BY,但問題是它不允許我對下級表(st)中的字段執行查詢。

任何有關適當邏輯的幫助將不勝感激。

這是一個在派生表子查詢中執行GROUP BY的解決方案,因此每個電影標題僅獲得一行,並由此計算ROW_NUMBER()

然后將派生表的結果再次連接到外部查詢中的st 每個電影標題仍將有多行,但是RowNum將重復,因此您可以正確過濾@pageIndex

SELECT * FROM
(
    SELECT ROW_NUMBER() OVER(ORDER BY " + orderField + @") AS RowNum,
           mt.ID AS mt_ID,
           mt.title AS mt_title,
           [...]
    FROM mt AS mt 
    INNER JOIN sttable AS st ON mt.ID =st.ID
    WHERE mt.title = @variable
    GROUP BY mt.ID
) mt1
INNER JOIN sttable AS st1 ON (mt1.ID = st1.ID)
WHERE mt1.RowNum BETWEEN 
    ((@pageIndex - 1) * @pageSize + 1) AND @pageIndex*@pageSize;

每當值RowNum更改時,就必須在顯示代碼中循環外部查詢的結果,並開始新的輸出行。 這是一個非常明顯的技術。

如果您想做類似MySQL的GROUP_CONCAT()函數的操作,那么在Microsoft SQL Server中這很棘手(我假設您使用的是Microsoft)。

請參閱http://blog.shlomoid.com/2008/11/emulation-mysqls-groupconcat-function.html之類的博客,這些博客描述了FOR xml PATH ('')技巧的用法。

PS:鑒於您的口頭描述,您的示例SQL查詢沒有任何意義,因此我盡力寫出了一些有意義的文章。 不保證它與您的架構匹配。


發表您的評論:我認為您不需要按子查詢中st的任何列進行排序。 我打算在子查詢的選擇列表中不包含st中的列。 在子查詢中加入st的實例的唯一原因是將mt的行限制為在st中具有匹配行的行。 但是GROUP BY mt.ID確保每行mt只有一行(實際上,因為這是SQL Server而不是MySQL,因此您需要在GROUP BY子句中命名select-list的所有mt列)。


重新發表您的第二條評論:

我想首先顯示具有最新添加的對應st記錄的mt行

如果使用分組功能,則可以將其他列添加到分組查詢中。 例如,每組mt的最新date_addedMAX(st.date_added) ,您可以將此列添加到子查詢中。

但是,請勿在子查詢中使用ORDER BY 幾乎沒有任何理由對子查詢進行排序,因為通過在JOIN中使用子查詢結果或您將在其中使用子查詢的其他操作,無論如何順序都可以更改。

您應該對外部查詢進行排序:

SELECT * FROM
(
    SELECT ROW_NUMBER() OVER(ORDER BY " + orderField + @") AS RowNum,
           mt.ID AS mt_ID,
           mt.title AS mt_title,
           [...] -- other mt.* columns
           MAX(st.date_added) AS latest_date_added
    FROM mt AS mt 
    INNER JOIN sttable AS st ON mt.ID =st.ID
    WHERE mt.title = @variable
    GROUP BY mt.ID, -- other mt.* columns
) mt1
INNER JOIN sttable AS st1 ON (mt1.ID = st1.ID)
WHERE mt1.RowNum BETWEEN 
    ((@pageIndex - 1) * @pageSize + 1) AND @pageIndex*@pageSize
ORDER BY mt1.latest_date_added DESC, st1.date_added DESC;

我認為您不需要同時擁有這兩個功能:

FROM mt AS mt 
  st AS st

和這個:

INNER JOIN sttable AS st on mt.ID = st.ID

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM