我有一个包含一些值的简单SQL表,例如:
id | value (table 'values')
----------
0 | 4
1 | 7
2 | 9
我想迭代这些值,并在如下的查询中使用它们:
SELECT value[0], x1
FROM (some subquery where value[0] is used)
UNION
SELECT value[1], x2
FROM (some subquery where value[1] is used)
...
etc
为了获得这样的结果集:
4 | x1
7 | x2
9 | x3
它必须在SQL中,因为它实际上代表数据库视图。当然真正的查询要复杂得多,但我试图在尽可能保持本质的同时简化问题。
我认为我必须从值中选择并加入子查询,但由于该值应该在子查询中使用,我将失去如何实现这一点。
编辑:我过分简化了我的问题;实际上我想从子查询中获得2行,而不仅仅是一行。
编辑2:正如我所建议的那样,我发布了真实的查询。我简化了一下以使其更清晰,但它是一个有效的查询,问题就在那里。请注意,我已经硬编码了值' 2'在这个查询中两次。我想用不同表中的值替换它,在上面的示例表中,我希望将此查询的组合结果的结果集以4,7和9作为值而不是当前硬编码的2。
SELECT x.fantasycoach_id, SUM(round_points)
FROM (
SELECT DISTINCT fc.id AS fantasycoach_id,
ffv.formation_id AS formation_id,
fpc.round_sequence AS round_sequence,
round_points,
fpc.fantasyplayer_id
FROM fantasyworld_FantasyCoach AS fc
LEFT JOIN fantasyworld_fantasyformation AS ff ON ff.id = (
SELECT MAX(fantasyworld_fantasyformationvalidity.formation_id)
FROM fantasyworld_fantasyformationvalidity
LEFT JOIN realworld_round AS _rr ON _rr.id = round_id
LEFT JOIN fantasyworld_fantasyformation AS _ff ON _ff.id = formation_id
WHERE is_valid = TRUE
AND _ff.coach_id = fc.id
AND _rr.sequence <= 2 /* HARDCODED USE OF VALUE */
)
LEFT JOIN fantasyworld_FantasyFormationPlayer AS ffp
ON ffp.formation_id = ff.id
LEFT JOIN dbcache_fantasyplayercache AS fpc
ON ffp.player_id = fpc.fantasyplayer_id
AND fpc.round_sequence = 2 /* HARDCODED USE OF VALUE */
LEFT JOIN fantasyworld_fantasyformationvalidity AS ffv
ON ffv.formation_id = ff.id
) x
GROUP BY fantasycoach_id
编辑3:我正在使用PostgreSQL。
答案 0 :(得分:3)
SQL与表一起使用,基本上涉及集合操作。没有明确的迭代,通常不需要任何迭代。特别是,您所描述的最简单的实现方式是:
SELECT value, (some subquery where value is used) AS x
FROM values
但请注意,相关的子查询,例如查询性能非常困难。根据您尝试执行的操作的详细信息,可以围绕简单连接,不相关的子查询或类似的,性能更好的替代方案来构建它。
<强>更新强>
鉴于问题的更新表明子查询预计会为表values
中的每个值产生多行,与示例结果相反,似乎更好的方法是重写子查询作为主要查询。如果它还没有这样做(可能即使它确实如此)那么它会将表values
作为另一个基表连接。
更新2:
鉴于现在提供的真实查询,这就是表values
中的值可以合并到其中的方式:
SELECT x.fantasycoach_id, SUM(round_points) FROM
(
SELECT DISTINCT
fc.id AS fantasycoach_id,
ffv.formation_id AS formation_id,
fpc.round_sequence AS round_sequence,
round_points,
fpc.fantasyplayer_id
FROM fantasyworld_FantasyCoach AS fc
-- one row for each combination of coach and value:
CROSS JOIN values
LEFT JOIN fantasyworld_fantasyformation AS ff
ON ff.id = (
SELECT MAX(fantasyworld_fantasyformationvalidity.formation_id)
FROM fantasyworld_fantasyformationvalidity
LEFT JOIN realworld_round AS _rr
ON _rr.id = round_id
LEFT JOIN fantasyworld_fantasyformation AS _ff
ON _ff.id = formation_id
WHERE is_valid = TRUE
AND _ff.coach_id = fc.id
-- use the value obtained from values:
AND _rr.sequence <= values.value
)
LEFT JOIN fantasyworld_FantasyFormationPlayer AS ffp
ON ffp.formation_id = ff.id
LEFT JOIN dbcache_fantasyplayercache AS fpc
ON ffp.player_id = fpc.fantasyplayer_id
-- use the value obtained from values again:
AND fpc.round_sequence = values.value
LEFT JOIN fantasyworld_fantasyformationvalidity AS ffv
ON ffv.formation_id = ff.id
) x
GROUP BY fantasycoach_id
特别注意构成两个表的叉积的CROSS JOIN
;这与没有任何连接谓词的INNER JOIN
相同,如果需要,可以这样写。
总体查询可能至少有点简化,但我不这样做,因为它是一个工作示例而不是实际的生产查询,因此不清楚其他更改会转化为实际应用程序。
答案 1 :(得分:3)
在示例中,我创建了两个表。看看外表如何在内部选择中使用别名?
SELECT T.[value], (SELECT [property] FROM Table2 P WHERE P.[value] = T.[value])
FROM Table1 T
这是一种更好的表现方式
SELECT T.[value], P.[property]
FROM Table1 T
INNER JOIN Table2 p
on P.[value] = T.[value];
Table 2
可以是QUERY而不是真实的表
使用cte
计算您的值,然后重新加入主表。这样,您可以将子查询逻辑与最终查询分开。
WITH cte AS (
SELECT
T.[value],
T.[value] * T.[value] as property
FROM Table1 T
)
SELECT T.[value], C.[property]
FROM Table1 T
INNER JOIN cte C
on T.[value] = C.[value];
答案 2 :(得分:0)
将计算提取到SELECT
子句中调用的函数并对结果集的每一行执行可能会有所帮助
以下是SQL Server CREATE FUNCTION的文档。它可能类似于您正在使用的任何数据库系统,如果没有,您可以轻松地使用谷歌。
以下是创建函数并在查询中使用它的示例:
CREATE FUNCTION DoComputation(@parameter1 int)
RETURNS int
AS
BEGIN
-- Do some calculations here and return the function result.
-- This example returns the value of @parameter1 squared.
-- You can add additional parameters to the function definition if needed
DECLARE @Result int
SET @Result = @parameter1 * @parameter1
RETURN @Result
END
以下是在查询中使用上述示例函数的示例。
SELECT v.value, DoComputation(v.value) as ComputedValue
FROM [Values] v
ORDER BY value