[英]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_added
為MAX(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.