2017-07-25 42 views
0

我有一個表格員工和一個表格銷售處於一對多關係。員工將包含名稱,電子郵件,身份證等字段,銷售將包括諸如國家,銷售數量,員工ID等信息。查找相關表格中是否存在

我現在想要做的是找到是否爲每個員工如果條目在銷售表中存在特定國家/地區。

我的輸出應該是這個樣子

Employee.name,Employee.email,銷往加拿大

在「銷往加拿大」我只是希望把在1或0,這取決於如果每個員工都有銷售條目,滿足特定國家的條件。

我已經嘗試過了是這樣的:

SELECT emp.name 
     ,emp.email 
     ,(SELECT COUNT(1) FROM sales sa JOIN employee emp ON emp.ID = sales.employeeID 
     WHERE sales.country = 'Canada') as "Sold to Canada" 
FROM employee emp 

這導致填充了一些比1高得多的「銷往加拿大」,因爲我認爲它返回,都使得員工總數銷售到加拿大而不是每個特定員工的信息。

回答

2

有很多方法對皮膚一隻貓。其中一個更好的是如下:

SELECT emp.name, emp.email, ISNULL(Sold, 0) AS [Sold to Canada] 
FROM employee AS emp 
    LEFT JOIN 
      (SELECT 1 AS Sold, employeeID 
      FROM sales 
      WHERE sales.country = 'Canada' 
      GROUP BY employeeID) AS CanadaSales 
     ON emp.ID = CanadaSales.employeeID 

評論:

這是不使用相關子查詢中SELECT部分,因爲這可能導致低效的查詢計劃,因此緩慢的查詢性能是個好主意。

更新: 如果需要返回多個國家的結果,我會用PIVOT

SELECT emp.name, emp.email, ISNULL(Canada, 0) AS SoldCanada, ISNULL(Australia, 0) AS SoldAustralia /*, ISNULL([another country], 0) AS [Sold Yet another country] */ 
FROM employee AS emp 
    LEFT JOIN 
     (SELECT * 
     FROM 
      ( 
       -- List of Country Employees 
       SELECT 1 AS Sold, employeeID, country 
       FROM sales 
       GROUP BY employeeID, country) AS EmpCountrySales 
      PIVOT 
      (
       -- For each country present return 1, else NULL 
       MAX(Sold) FOR country IN([Canada], [Australia] /* , [another country] */) 
      ) AS pvt 
     ) AS EmployeeSales 

     ON emp.ID = EmployeeSales.employeeID 

評論: PIVOT功能需要太多的括號內。

+0

哇,這個解決方案是快速的!與使用'Case When'相比,這樣執行的速度要快100倍 如果我想查看多個國家/地區,我可以通過添加更多連接來擴展它嗎?我試了一下,它似乎工作得很好,但我想確保這是正確的方法。 – Haris

+1

@哈里斯,看到更新的答案 – Alex

2

您可以用CASE做到這一點:

SELECT emp.name, 
    emp.email, 
    (CASE WHEN emp.ID IN (SELECT sales.employeeID FROM sales WHERE sales.country = 'Canada') THEN 1 ELSE 0 END) AS [Sold to Canada] 
FROM employee emp 
2

這是直接翻譯成SQL使用相關子查詢 :-)

SELECT emp.name 
     ,emp.email 
     ,CASE 
     WHEN EXISTS(SELECT * FROM sales sa 
        WHERE emp.ID = sa.employeeID 
         AND sa.country = 'Canada') 
     THEN 1 
     ELSE 0 
     END as "Sold to Canada" 
FROM employee emp 
3

@Alex已經給出了很好的答案。但是,如果您想避免子查詢,則可以使用此解決方案。

SELECT MIN(e.Name) AS EmployeeName 
    , MIN(e.Email) AS Email 
    , CASE WHEN MIN(EmployeeID) IS NOT NULL THEN 1 ELSE 0 END AS [Sold To Canada] 
FROM Employee AS e 
LEFT JOIN Sales AS s ON (s.EmployeeID = e.ID AND Country = 'Canada') 
GROUP BY e.ID;