使用MIN()代替前1个SQL查询

时间:2019-02-21 11:44:34

标签: sql-server

作品

employeeName    companyName     salary
John            Samsung         10000
Paul            Apple           15000
Petr            Samsung          7500

请考虑上面给出的表“ Works”。我想“找到工资单(员工的总工资)最少的公司”,在这种情况下为Apple。我已经使用以下查询实现了所需的输出:

select top 1 SUM(salary) as sal, companyName from Works group by companyName order by sal

但是,我想使用MIN()函数而不是top函数进行查询,因为它在SQL Server中允许,但在所有dbms中都不允许。任何帮助将不胜感激。

5 个答案:

答案 0 :(得分:2)

如果您不想使用TOP,则可以将CTE与MIN一起使用。当然,如果您有多个具有相同最小值的行,则将全部返回:

WITH VTE AS(
    SELECT *
    FROM (VALUES('J','S',10000),
                ('P','A',15000),
                ('S','S',7500))V(Emp, Comp, Sal)),
CTE AS(
    SELECT Comp,
           Sal,
           MIN(Sal) OVER () AS MinSal
    FROM VTE)
SELECT Comp,
       Sal
FROM CTE
WHERE Sal = MinSal;

根据注释中的 new 信息进行编辑...(“在上述示例中,“苹果的工资总额为1万5千,三星的工资总额为17.5万,因此苹果的工资总额最小”。 em>),这应该得到OP所追求的结果。我仍然认为TOP在这里会更加简洁。

WITH VTE AS(
    SELECT *
    FROM (VALUES('J','S',10000),
                ('P','A',15000),
                ('S','S',7500))V(Emp, Comp, Sal)),
Tots AS(
    SELECT Comp,
           SUM(sal) AS TotSal
    FROM VTE
    GROUP BY Comp),
CTE AS (
    SELECT Comp,
           TotSal,
           MIN(TotSal) OVER () AS MinTotSal
    FROM Tots)
SELECT Comp,
       TotSal
FROM CTE
WHERE TotSal = MinTotSal;

答案 1 :(得分:0)

我认为下面的结果行与使用TOP 1的结果行相同。 但是,这不是很好。原因是执行成本非常昂贵。

DECLARE salary_cursor CURSOR FOR 
SELECT companyName, MIN(sal) as sal
FROM (
    SELECT SUM(salary) AS sal, companyName FROM Works group by companyName 
    ) T
GROUP BY companyName; 

OPEN salary_cursor; 

FETCH NEXT FROM salary_cursor; 


CLOSE salary_cursor;  
DEALLOCATE salary_cursor;

答案 2 :(得分:0)

如果我理解正确,那么您想获得最高平均工资。如果是这样,请尝试使用以下代码:

BaseEdgeDocument myObject = new BaseEdgeDocument("TurmaA/asd","TurmaA/testepedro");
myObject.addAttribute(nome.getField(), nome.getValue());
collection.insertEdge(myObject, new EdgeCreateOptions());

输出:

DECLARE @table TABLE
(
    employeeName VARCHAR(50),
    companyName VARCHAR(50),
    salary INT
)

INSERT INTO @table
(
    employeeName,
    companyName,
    salary
)
VALUES
('John','Samsung',10000),
('Paul','Apple',15000),
('Petr','Samsung',7500)

;WITH cte AS (
SELECT 
  tbl.companyName
, AVG(tbl.salary) AvgSalary
FROM @table tbl
GROUP BY tbl.companyName
)
SELECT 
  q.companyName
, q.AvgSalary
FROM 
cte q
WHERE  q.AvgSalary IN (SELECT MAX(cte.AvgSalary) FROM cte )

答案 3 :(得分:0)

尝试这个简单的例子。这不是完美的,并且可能导致出现重复的问题。

  SELECT * FROM (
                SELECT SUM(w.salary) sumSalary, w.cpyname FROM @work AS w
                GROUP BY w.cpyname) g
GROUP BY sumSalary, g.cpyname
HAVING g.sumSalary =  (
SELECT MIN(f.sumSalary)  FROM (
SELECT SUM(w.salary) sumSalary, w.cpyname FROM @work AS w
GROUP BY w.cpyname)f )

编辑 我错过了OP按公司名称求和的地方

答案 4 :(得分:0)

查询以准备虚拟数据:

declare @Works TABLE 
(
  EmployeeName varchar(100),
  CompanyName varchar(100),
  Salary int  
)

Insert into @Works Select 'John', 'Samsung', 10000
Insert into @Works Select 'Paul', 'Apple', 15000
Insert into @Works Select 'Petr', 'Samsung', 7500
;

实际查询:

WITH CTE AS 
(SELECT CompanyName, SUM(Salary) as TotalSalary FROM @Works GROUP BY CompanyName)
SELECT CompanyName, TotalSalary FROM CTE WHERE TotalSalary = 
(SELECT MIN(TotalSalary) FROM CTE)

输出

enter image description here