我对sql查询有疑问。我真正需要的是选择所有用户并选择他们最喜欢的3个类别。现在,我将它分为两个不同的查询:
async.waterfall([
cbUsersArray => {
sqlRequest(`
SELECT st.id as studentID, st.firstName as studentFirstName, st.email as studentEmail
FROM dbo.Students st
WHERE st.isActive = 1
AND st.deleted = 0
AND IsNull(st.firstName, '') != ''
AND IsNull(st.email, '') != ''
`, (sqlErr, sqlRes) => {
if(sqlErr){
cbUsersArray(sqlErr)
} else {
cbUsersArray(null, sqlRes)
}
})
},
(usersArray, cbUsersArrayWithFavCats) => {
async.eachLimit(usersArray, asyncEachLimit, (u, cb) => {
sqlRequest(`SELECT TOP 3 bts.BrandCategoryID as catID FROM Students st
JOIN SaleView ss ON (st.ID=ss.userID)
JOIN Sales sa ON (sa.ID=ss.SaleID)
JOIN Brands b ON (b.ID=sa.BrandID)
JOIN KEY_BrandcategoryToSale bts ON (bts.SaleID=sa.ID)
WHERE st.ID = ${u['studentID']}
GROUP BY bts.BrandCategoryID
ORDER BY COUNT(bts.BrandCategoryID) desc`,(sqlErr, sqlRes) => {
if(sqlErr){
} else {
}
cb()
})
}, () => {
})
}
], () => {
})
有什么建议我如何在一个查询中组合它并得到类似的结果?
+----+-----------+-----------+-------------+------------------------------+
| ID | StudentID | FirstName | Email | FavoriteCategories |
+----+-----------+-----------+-------------+------------------------------+
| 1 | 123456 | Edward | ed@mail.com | [{c1ID:1},{c2ID:2},{c3ID:3}] |
+----+-----------+-----------+-------------+------------------------------+
OR
+----+-----------+-----------+-------------+--------+--------+--------+
| ID | StudentID | FirstName | Email | Cat1ID | Cat2ID | Cat3ID |
+----+-----------+-----------+-------------+--------+--------+--------+
| 1 | 123456 | Edward | ed@mail.com | 1 | 2 | 3 |
+----+-----------+-----------+-------------+--------+--------+--------+
答案 0 :(得分:0)
将第二个查询放在公用表expresions中,并在第一个查询中使用它。使用row_number查找第一,第二和第三最受欢迎的类别。 如果学生的类别少于三个,请使用外部联接。
with categories_cte as
(
SELECT row_number() over (partition by st.id order by COUNT(bts.BrandCategoryID) desc) rn,
st.id , bts.BrandCategoryID
FROM Students st
JOIN SaleView ss ON (st.ID=ss.userID)
JOIN Sales sa ON (sa.ID=ss.SaleID)
JOIN Brands b ON (b.ID=sa.BrandID)
JOIN KEY_BrandcategoryToSale bts ON (bts.SaleID=sa.ID)
GROUP BY st.id, bts.BrandCategoryID
)
SELECT st.id as studentID, st.firstName as studentFirstName, st.email as studentEmail,
c1.brandCategoryID cat1ID,c2.brandCategoryID cat2ID,c3.brandCategoryID cat3ID
FROM dbo.Students st
left join categories_cte c1 on st.id = c1.id and c1.rn = 1
left join categories_cte c2 on st.id = c2.id and c2.rn = 2
left join categories_cte c3 on st.id = c3.id and c3.rn = 3
WHERE st.isActive = 1 AND st.deleted = 0
AND IsNull(st.firstName, '') != '' AND IsNull(st.email, '') != ''
答案 1 :(得分:0)
您可以尝试以下查询
WITH favorites
AS (SELECT id,
MAX(CASE
WHEN row_seq = 1 THEN brandcategoryid
END) AS cat1ID,
MAX(CASE
WHEN row_seq = 2 THEN brandcategoryid
END) AS cat2ID,
MAX(CASE
WHEN row_seq = 3 THEN brandcategoryid
END) AS cat3ID
FROM (SELECT st.id,
bts.brandcategoryid,
ROW_NUMBER() OVER (
PARTITION BY st.id
ORDER BY bts.categorycount DESC) row_seq
FROM students st
JOIN saleview ss
ON ( st.id = ss.userid )
JOIN sales sa
ON ( sa.id = ss.saleid )
JOIN brands b
ON ( b.id = sa.brandid )
JOIN (SELECT saleid,
COUNT(brandcategoryid) AS CategoryCount
FROM key_brandcategorytosale
GROUP BY saleid) bts
ON ( bts.saleid = sa.id )) data
WHERE row_seq <= 3
GROUP BY id)
SELECT st.id AS studentID,
st.firstname AS studentFirstName,
st.email AS studentEmail,
favorites.cat1id,
favorites.cat2id,
favorites.cat3id
FROM dbo.students st
LEFT JOIN favorites
ON st.id = favorites.id
WHERE st.isactive = 1
AND st.deleted = 0
AND ISNULL(st.firstname, '') != ''
AND ISNULL(st.email, '') != ''