【问题标题】:Getting double JOIN and picking correct column inside SQL query在 SQL 查询中获取双重 JOIN 并选择正确的列
【发布时间】:2018-03-23 16:17:22
【问题描述】:

我试图在 SQL 查询中加入一些逻辑以获得所需的结果,而无需在后端代码中进行后处理逻辑。

下面是我现在的查询:

SELECT
  milestone.id,
  milestone.initiative_id,
  milestone.created,
  milestone.modified,
  status.name as "statusName",
  (COUNT(activity.id))::int as "activityCount",
  MAX(activity.end_on) AS "activityMaxEndOn",
  milestone.name,
  milestone.description,
  activity.status
FROM
  milestone
INNER JOIN
  status
ON
  status.id = milestone.status
LEFT JOIN
  activity
ON
  activity.milestone_id = milestone.id
GROUP BY
  milestone.id, status.name, activity.status

它返回通过在 status 表上 JOINing milestone status 检索到的 statusName。它还返回id 的状态activity 已加入此milestone。我需要:

- Get `status.name` for the `activity` as well, not just `id.
- Get count() of `DISTINCT` status entries from `activity` for each status

例如列:milestoneStatusName,每个状态的 count(statusX)。

【问题讨论】:

  • 你正在使用哪个数据库??
  • Postgres - 理想情况下,获得通用 SQL 解决方案会很好,例如不是存储过程,而是查询。如果可以的话,
  • ::int 是什么意思(这不是 sql 标准)
  • 样本数据和期望的结果真的很有帮助。

标签: sql join nested subquery


【解决方案1】:
declare @SQL_toExecute nvarchar(max) = ''
declare @Status nvarchar(100) = ''
declare @activitycount bigint = 0
declare @activityend datetime2(7)

delacre @milestoneid... etc

declare milestone_cursor cursor local static forward_only read_only
for
SELECT
  milestone.id,
  milestone.initiative_id,
  milestone.created,
  milestone.modified,
--  status.name as "statusName",
-- (COUNT(activity.id))::int as "activityCount",
--  MAX(activity.end_on) AS "activityMaxEndOn",
  milestone.name,
  milestone.description,
  activity.status
FROM
  milestone
/* INNER JOIN
  status
ON
  status.id = milestone.status
LEFT JOIN
  activity
ON
  activity.milestone_id = milestone.id
GROUP BY
  milestone.id, status.name, activity.status */

open milestone_cursor

fetch next from milestone_cursor
 into @milestoneid..etc

while @@fetchstatus = 0
begin

select @Status = status
from status where ... milestoneId?

select @activitycount = count(1)
from table where... milestoneid?


select @activityend = max(date)
from table where... milestoneid?


set @SQL_to_Execute 
= @SQL_To_Execute 
+'SELECT '
+ convert(nvarchar(100), @milestoneid) + ' as Milestone'
+ ',' + convert(nvarchar(100), @status) + ' as status'
+ ',' + convert(nvarchar(100), @activityend ) + ' as activity end'
-- continue for all columns.

+ ' Union all '


fetch next from milestone_cursor
 into @milestoneid..etc
end


close milestone_cursor
deallocate milestone_cursor

-- in the end you will have an extra ' union all '

set @sql_to_execute = left(@sql_to_execute, len(@sql_to_execute)-len(' union all '))

exec sp_msexecutesql @SQL_to_execute

编辑:在选择之前添加了“,”,因此您不必担心它的末尾。

【讨论】:

    【解决方案2】:

    如果没有看到这些表的架构,这很难,但如果 activity.status 是一个 Id,那么你可以这样做:

    INNER JOIN activity ON status.id = activity.status
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-04-16
      • 2011-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-15
      相关资源
      最近更新 更多