我有一个表,这个表有一个布尔列,这个列用来过滤一些响应。我需要以元组的形式返回一个响应作为 {claimed, unclaimed}
(想象一下,这个表叫 winnings
)
在工作中,我做了两个单独的查询,以返回 claimed
然后 unclaimed
行,并手动构造响应,然后我采用了返回所有行而不检查布尔列,并在查询之外将其拆分。现在我想知道是否有一种方法可以让我在同一个表上运行一个单一的查询,并同时返回 claimed
和 unclaimed
作为单独的结果,主要是为了性能,希望它运行得更好。我试着用join来做,但它返回的是一个由两个项目组成的tuple列表,比如:我想:我想:我想:我想:我想:我想:我想:我想:我想:我想:我想:我想:我想:我想:我想:我想:我想:我想:我想:我想:我想:我想:我想:我想:我想:我想:我想:我想:我想:我想:我想:我想:我想:我想:我想:我想:我想:我想:我想:我想
[{claimed, unclaimed}, {claimed, unclaimed}]...
当我想要:
{claimed, unclaimed}
# OR
[{claimed, unclaimed}]
最多,没有更多的元组。请注意,我不是在运行原始查询,而是在使用一个库,所以如果术语不对,请原谅。
这是我最后运行的查询。
SELECT w0."claimed", w1."claimed"
FROM "winnings" AS w0
INNER JOIN "winnings" AS w1 ON TRUE
WHERE (w0."claimed" AND NOT (w1."claimed"))
LIMIT 10;
EDIT: 更多细节.
当我运行上面的查询时,我得到的结果是这样的。
=> SELECT w0."claimed", w1."claimed" FROM "winnings" AS w0 INNER JOIN "winnings" AS w1 ON TRUE WHERE (w0."claimed" AND NOT (w1."claimed")) LIMIT 10;
claimed | claimed
---------+---------
t | f
t | f
t | f
t | f
t | f
t | f
t | f
t | f
t | f
t | f
(10 rows)
在我使用的语言Elixir上,这个结果被转换为以下内容。
[
true: false,
true: false,
true: false,
true: false,
true: false,
true: false,
true: false,
true: false,
true: false,
true: false
]
这是一个关键字列表,内部是一个图元组列表,如下图所示 [{true, false}, {true, false}]
- 我想要。[{[true, true], [false, false]}]
意思是我想要两个列表,每个列表都有各自的行, 一个列表只有人认领,另一个列表只有无人认领。
我并不介意它输出的类型,只要它包括两个列表和它们的行,就像我说的那样。
要从行列表中获取第一列,你可以使用 Enum.map/2
来获取每个元组的第一个元素。
Enum.map(rows, &elem(&1, 0))
如果你是精灵宝的新手 If you're a newcomer to elixir, 这个& 语法可能会有点混乱 the & syntax may be a bit confusing. 这段代码是
Enum.map(rows, fn field -> elem(field, 0) end)
你可以把它做成一个函数,像这样对所有的列都这样做。
def columnize(rows = [first_row | _]) when is_tuple(first_row) do
for column <- 1..tuple_size(first_row), do: Enum.map(rows, &elem(&1, column - 1))
end
def columnize([]) do
[]
end
hd/1
是一个用来获取列表中第一个元组的函数。列表中的 = [first_row | _]
部分保证参数是一个至少有一个元素的列表;而 when is_tuple(first_row)
确保至少第一行是一个元组。
如果您想了解更多关于 for
这是一个 理解力.
请注意,这个函数假设所有的行都有相同的列数,并且是tuple(在查询结果中应该是真的,但在其他情况下可能不是),并且会抛出一个 ArgumentError
如果第一行比其他行宽,则会出现错误。如果列表中的其他元素不是元组,它也会导致错误。
不过这感觉很单调。这也许是XY的问题吗?