【问题标题】:Trying to select multiple columns on an inner join query with group and where clauses尝试使用 group 和 where 子句在内部联接查询中选择多个列
【发布时间】:2014-02-20 14:54:26
【问题描述】:

我正在尝试运行一个查询,它会给我一个求和函数,然后从一个连接表中选择两列,然后按我给它们的唯一 ID 对这些数据进行分组。这是我的原始查询,它有效。

SELECT Sum (Commission_Paid)
FROM [INTERN_DB2].[dbo].[PaymentList]
INNER JOIN [INTERN_DB2]..[RealEstateAgentList]
ON RealEstateAgentList.AgentID = PaymentList.AgentID
WHERE Close_Date >= '1/1/2013' AND Close_Date <= '12/31/2013'
GROUP BY RealEstateAgentList.AgentID

我已尝试以下查询,但我不断收到错误,我不知道为什么。它说它是一个语法错误。

SELECT Sum (Commission_Paid)
FROM [INTERN_DB2].[dbo].[PaymentList]
INNERJOIN [INTERN_DB2]..[RealEstateAgentList](
Select First_Name, Last_Name
From [Intern_DB2]..[RealEstateAgentList]
Group By Last_name
)
ON RealEstateAgentList.AgentID = PaymentList.AgentID
WHERE Close_Date >= '1/1/2013' AND Close_Date <= '12/31/2013'
GROUP BY RealEstateAgentList.AgentID

【问题讨论】:

  • 你有两个点来自 [Intern_DB2]..[RealEstateAgentList] 应该只有一个
  • 其实这两个点是对的。他们可以(并且可能应该)在它们之间放置一个 [dbo],但这不是必需的。

标签: sql sql-server-2012 ssms


【解决方案1】:

您的查询有多个问题:

SELECT rl.AgentId, rl.first_name, rl.last_name, Sum(Commission_Paid)
FROM [INTERN_DB2].[dbo].[PaymentList] pl inner join
     (Select agent_id, min(first_name) as first_name, min(last_name) as last_name
      From [Intern_DB2]..[RealEstateAgentList]
      GROUP BY agent_id
     ) rl
     ON rl.AgentID = pl.AgentID
WHERE Close_Date >= '2013-01-01' AND Close_Date <= '2013-12-31'
GROUP BY rl.AgentID, rl.first_name, rl.last_name;

以下是一些变化:

  • INNERJOIN --> inner join.
  • 修复了表名旁边的子查询语法。
  • 删除了名字和姓氏的列。它们没有被使用。
  • 将子查询更改为包含agent_id
  • 在外部聚合中添加了agent_idfirst_namelast_name,这样您就可以知道值的来源。
  • 将日期格式更改为不那么模糊的标准格式。
  • 为子查询添加了表别名。

我怀疑代理列表上的子查询并不重要。您可能可以这样做:

SELECT rl.AgentId, rl.first_name, rl.last_name, Sum(pl.Commission_Paid)
FROM [INTERN_DB2].[dbo].[PaymentList] pl inner join
     [Intern_DB2]..[RealEstateAgentList] rl
     ON rl.AgentID = pl.AgentID
WHERE pl.Close_Date >= '2013-01-01' AND pl.Close_Date <= '2013-12-31'
GROUP BY rl.AgentID, rl.first_name, rl.last_name;

编辑:

我很高兴这个解决方案有所帮助。当您继续编写查询时,请尝试始终执行以下操作:

  1. 使用作为表名缩写的表别名。
  2. 在引用列时始终使用表别名。
  3. 使用日期常量时,要么使用“YYYY-MM-DD”格式,要么使用convert() 以使用指定格式转换字符串。 (后者实际上是更安全的方法,但前者更方便,几乎适用于所有数据库。)
  4. 注意错误信息;它们可以在 SQL Server 中提供信息(不幸的是,其他数据库不是那么清楚)。
  5. 格式化您的查询,以便其他人能够理解。这也将帮助您理解和调试您的查询。我有一种非常特殊的格式风格(此时没有人会改变);重要的不是特定的样式,而是能够“看到”查询在做什么。我的风格记录在我的“使用 SQL 和 Excel 进行数据分析”一书中。

还有其他规则,但这些是入门的好方法。

【讨论】:

  • 不错的答案。我一直在编辑我的,因为我一直在原始查询中发现问题。我最终删除了我的答案,因为我认为您的总结非常好,并且您完全删除子查询的最终建议比我尝试修复查询同时仍然保留它更好。
  • 完美答案!谢谢你,我正在经历一场火灾,你们帮了我很大的忙!
  • 戈登,谢谢您的指点!这就是为什么我来堆栈溢出,向我的更好学习,谢谢。 :)
【解决方案2】:
SELECT Sum (Commission_Paid)
FROM [INTERN_DB2].[dbo].[PaymentList] pl
INNER JOIN (
    Select First_Name, Last_Name
    From [Intern_DB2]..[RealEstateAgentList]
    Group By Last_name
) x ON x.AgentID = pl.AgentID
WHERE Close_Date >= '1/1/2013' 
    AND Close_Date <= '12/31/2013'
GROUP BY RealEstateAgentList.AgentID

这就是查询的外观...但是,如果您对名字和姓氏进行子查询,则还必须将它们包含在 group by 中。假设 Close_Date 在 PaymentList 表中,这就是我编写查询的方式:

SELECT 
    al.AgentID, 
    al.FirstName, 
    al.LastName, 
    Sum(pl.Commission_Paid) AS Commission_Paid
FROM [INTERN_DB2].[dbo].[PaymentList] pl
INNER JOIN [Intern_DB2].dbo.[RealEstateAgentList] al ON al.AgentID = pl.AgentID
WHERE YEAR(pl.Close_Date) = '2013'
GROUP BY al.AgentID, al.FirstName, al.LastName

在大多数情况下,子查询是邪恶的。这里不需要一个,因为您可以从连接中获取列。

【讨论】:

    猜你喜欢
    • 2019-08-18
    • 1970-01-01
    • 2019-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-19
    • 1970-01-01
    相关资源
    最近更新 更多