2017-05-22 44 views
0

我有一個關於sql查詢的問題。我真正需要的是選擇所有用戶並選擇他們最喜歡的3個類別。現在,我把它兩個不同的查詢:SQL查詢。如何組合它們

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 | [email protected] | [{c1ID:1},{c2ID:2},{c3ID:3}] | 
+----+-----------+-----------+-------------+------------------------------+ 

OR

+----+-----------+-----------+-------------+--------+--------+--------+ 
| ID | StudentID | FirstName | Email | Cat1ID | Cat2ID | Cat3ID | 
+----+-----------+-----------+-------------+--------+--------+--------+ 
| 1 | 123456 | Edward | [email protected] |  1 |  2 |  3 | 
+----+-----------+-----------+-------------+--------+--------+--------+ 
+3

向我們展示的樣品結果從目前的查詢,他們應該如何進行組合。 (以及格式化文本。) – jarlh

+0

你好,這樣的事情。 –

+0

通過將Students表加入到第二個sql語句中,您將得到三行(每個類別一個),您可以爲每個學生解析這三行。 – Sourcery

回答

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, '') != '' 
+0

謝謝,它的工作原理。但知道我有另一個問題。很長的執行時間和服務器DTU 96-100%。 –

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