SQL查询。如何结合它们

时间:2017-05-22 08:44:53

标签: sql sql-server

我对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 |
+----+-----------+-----------+-------------+--------+--------+--------+

2 个答案:

答案 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, '') != ''