查找相关表中是否存在某些内容

时间:2017-07-25 08:09:20

标签: sql sql-server

我有一个表员工和一个表销售,这是一对多的关系。员工将包含姓名,电子邮件,身份证等字段,销售额将包括国家,销售数量,员工ID等信息。

我现在要做的是查找每个员工是否存在特定国家/地区的销售表中的条目。

我的输出应该类似于

Employee.name,Employee.email,Soldled to Canada

In&34;出售给加拿大"我只想输入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,因为我认为它返回了向加拿大销售的员工总数,而不是每个特定员工的信息。

4 个答案:

答案 0 :(得分: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;

答案 1 :(得分: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 :(得分: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 :(得分: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函数需要太多括号。