【问题标题】:How to simplify this subquery?如何简化这个子查询?
【发布时间】:2015-02-04 08:56:16
【问题描述】:

我从http://www.programmerinterview.com/index.php/database-sql/derived-table-vs-subquery/ 看到了这个子查询,它以下面的子查询为例,但说它可以写得更简单。谁能告诉我该怎么做?谢谢!

一个名为employee 的表,其中包含employee_name、last_name、employee_salary 和employee_number 列。我们希望找到所有薪水高于平均水平的员工。

   select employee_name 
    from employee
    where employee_salary >
    (select avg(employee_salary)
            from employee)

【问题讨论】:

标签: mysql sql sql-server select subquery


【解决方案1】:

试试这个:

SELECT employee_name 
FROM employee e 
INNER JOIN (SELECT AVG(employee_salary) salary FROM employee) e1 ON e.employee_salary > e1.salary;

SELECT employee_name 
FROM employee e 
WHERE EXISTS (SELECT 1 FROM employee e1 WHERE e.employee_salary > AVG(e1.employee_salary)); 

【讨论】:

    【解决方案2】:

    我认为您的查询设计得很好。 使用 JOIN 效率会降低,并且 HAVING 子句将在检索后过滤数据。您将获取所有员工,然后过滤平均工资。

    【讨论】:

      【解决方案3】:

      希望这会有所帮助

      --DECLARE A TABLE VARIABLE
      DECLARE @Emp AS TABLE
      
      (
           ID                 INT
          ,EMPLOYEE_NAME      VARCHAR(50)
          ,EMPLOYEE_SALARY    NUMERIC(18,2)
      
      )
      -- ADD SOME VALUES TO THE TABLE
      INSERT INTO @Emp
      VALUES (1,'DANNY',7000),(2,'JOHN',10000),(3,'DAVID',1000)
      
      --AVERAGE SALARY IS 6000..
      
      --USING COMMON TABLE EXPRESSIONS
          ; WITH CTE AS
           (
              SELECT 
                  AVG(EMPLOYEE_SALARY)  AS AVGSALARY
              FROM @EMP       
          )
              SELECT 
                  EMPLOYEE_NAME
              FROM 
                  @Emp    EMPLOYEE    -- MY TABLE
              INNER JOIN
                  CTE
              ON
                  EMPLOYEE_SALARY>CTE.AVGSALARY
      

      【讨论】:

        【解决方案4】:

        您可以使用OVER 子句计算average 的薪水以及当前员工的薪水是否大于它。很遗憾,window 函数不能在 where 子句中使用,所以你也应该使用命令表表达式。

        DECLARE @employee TABLE
        (
             [employee_name] VARCHAR(12)
            ,[employee_salary] INT
        )
        
        INSERT INTO @employee ([employee_name], [employee_salary])
        VALUES ('Empl1', 100)
              ,('Empl2', 200)
              ,('Empl3', 300)
              ,('Empl4', 400)
              ,('Empl5', 500)
              ,('Empl6', 600)
              ,('Empl7', 700)
              ,('Empl8', 800)
        
        -- your query
         select employee_name 
            from @employee
            where employee_salary >
            (select avg(employee_salary)
                    from @employee)
        
        -- alternative query
        ;WITH DataSource AS
        (
             select employee_name
                   ,employee_salary - AVG(employee_salary) OVER () AS diff
             from @employee
         )
         SELECT employee_name
         FROM DataSource
         WHERE diff > 0
        

        【讨论】:

        • 有趣的方法,但是针对 300,000 行的表测试这两个查询,原始查询的执行比使用 OVER 的查询要好约 5.5 倍(相对于批处理的成本为 15% 与 85%)。
        【解决方案5】:

        sql server 2012

            select iif(((employee_salary) > (SELECT avg(employee_salary) FROM employee)),
                    employee_name ,null) employee_name 
            FROM employee
            group by employee_name,employee_salary 
        

        【讨论】:

        • 这个查询甚至无法编译。
        猜你喜欢
        • 2010-09-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多