SQL 到 select 项基于同一 table 中的多个条件并具有串联结果
SQL to select items based on multiple conditions in same table with concatenated result
我有以下场景:
我正在两个表中存储与迁移相关的信息:
log
-------------
log_id
release_id
environment_id
status
log_details
----------------------
log_detail_id
log_id
release_id
item_name
type
file_name
version_number
status
remarks
现在我需要 select 一个环境中存在而另一个环境中不存在的文件名。我正在使用如下查询:
SELECT file_name, version_number from log_details JOIN log ON log_details.log_id = log.log_id
WHERE environment_id = 'SOURCE_ENVIRONMENT_ID' AND log_details.status='SUCCESS'
AND file_name NOT IN (
SELECT DISTINCT file_name from log_details JOIN log ON log_details.log_id = log.log_id
WHERE environment_id = 'TARGET_ENVIRONMENT_ID' AND log_details.status='SUCCESS'
);
这工作正常并显示文件名和相应的版本号。现在根据新要求,我还需要比较文件的版本。也就是说,即使文件名存在于两个环境中,但版本不同,它也应该显示文件名。
所以 select 应该像 file_name, source_version, target_version
一样显示 3 列。如果文件在目标上不存在,它应该显示 NA
。我该怎么做?
更新:添加fiddle:
稍后可能会更新以反映您提供的任何示例数据,但这听起来很适合您的目的:
SELECT
src.file_name,
src.version_number as source_version,
IFNULL(tgt.version_number, 'NA') as target_version
FROM (
SELECT
log_details.file_name,
log_details.version_number
FROM log_details
JOIN logs ON log_details.log_id = logs.log_id
WHERE logs.environment_id = 'DEV'
AND logs.STATUS = 'SUCCESS'
) src
LEFT JOIN (
SELECT
log_details.file_name,
log_details.version_number
FROM log_details
JOIN logs ON log_details.log_id = logs.log_id
WHERE logs.environment_id = 'PROD'
AND logs.status='SUCCESS'
) tgt ON src.file_name = tgt.file_name
作为奖励,您仍然可以使用 WHERE tgt.version_number IS NULL
获得原始查询的结果。
编辑:
使用您的 fiddle 数据,并假设 DEV 是您的“源”环境,这将导致输出:
+-----------------------------------------------+
|file_name |source_version | target_version|
+-----------------------------------------------+
|file_name_1 | 100 | 101 |
|file_name_2 | 100 | NA |
|file_name_3 | 100 | NA |
+-------------------------------+---------------+
这似乎不是很有用,我想如果你提供一个明确的“预期结果”布局,你想要的和你要求的不一样,但我只是猜测。
我有以下场景:
我正在两个表中存储与迁移相关的信息:
log
-------------
log_id
release_id
environment_id
status
log_details
----------------------
log_detail_id
log_id
release_id
item_name
type
file_name
version_number
status
remarks
现在我需要 select 一个环境中存在而另一个环境中不存在的文件名。我正在使用如下查询:
SELECT file_name, version_number from log_details JOIN log ON log_details.log_id = log.log_id
WHERE environment_id = 'SOURCE_ENVIRONMENT_ID' AND log_details.status='SUCCESS'
AND file_name NOT IN (
SELECT DISTINCT file_name from log_details JOIN log ON log_details.log_id = log.log_id
WHERE environment_id = 'TARGET_ENVIRONMENT_ID' AND log_details.status='SUCCESS'
);
这工作正常并显示文件名和相应的版本号。现在根据新要求,我还需要比较文件的版本。也就是说,即使文件名存在于两个环境中,但版本不同,它也应该显示文件名。
所以 select 应该像 file_name, source_version, target_version
一样显示 3 列。如果文件在目标上不存在,它应该显示 NA
。我该怎么做?
更新:添加fiddle:
稍后可能会更新以反映您提供的任何示例数据,但这听起来很适合您的目的:
SELECT
src.file_name,
src.version_number as source_version,
IFNULL(tgt.version_number, 'NA') as target_version
FROM (
SELECT
log_details.file_name,
log_details.version_number
FROM log_details
JOIN logs ON log_details.log_id = logs.log_id
WHERE logs.environment_id = 'DEV'
AND logs.STATUS = 'SUCCESS'
) src
LEFT JOIN (
SELECT
log_details.file_name,
log_details.version_number
FROM log_details
JOIN logs ON log_details.log_id = logs.log_id
WHERE logs.environment_id = 'PROD'
AND logs.status='SUCCESS'
) tgt ON src.file_name = tgt.file_name
作为奖励,您仍然可以使用 WHERE tgt.version_number IS NULL
获得原始查询的结果。
编辑:
使用您的 fiddle 数据,并假设 DEV 是您的“源”环境,这将导致输出:
+-----------------------------------------------+
|file_name |source_version | target_version|
+-----------------------------------------------+
|file_name_1 | 100 | 101 |
|file_name_2 | 100 | NA |
|file_name_3 | 100 | NA |
+-------------------------------+---------------+
这似乎不是很有用,我想如果你提供一个明确的“预期结果”布局,你想要的和你要求的不一样,但我只是猜测。