更新以从逗号分隔的列表中删除重复项

时间:2019-05-28 22:10:43

标签: sql postgresql duplicates

在我的Postgres数据库中,我有一个包含一些列的表,其中一列 final RecyclerView.OnScrollListener[] scrollListeners = new RecyclerView.OnScrollListener[viewHolder.getAdapterPosition()]; scrollListeners[viewHolder.getAdapterPosition()] = new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); ((OverViewRecyclerViewAdapter.PostViewHolder) viewHolder).recyclerViewfullData.removeOnScrollListener(scrollListeners[viewHolder.getAdapterPosition()]); ((OverViewRecyclerViewAdapter.PostViewHolder) viewHolder).recyclerViewfullData.scrollBy(dx, dy); ((OverViewRecyclerViewAdapter.PostViewHolder) viewHolder).recyclerViewfullData.addOnScrollListener(scrollListeners[viewHolder.getAdapterPosition()]); } }; ((OverViewRecyclerViewAdapter.PostViewHolder) viewHolder).recyclerViewfullData.addOnScrollListener(scrollListeners[viewHolder.getAdapterPosition()]); 的值如下:

B

我的预期输出应该是这样的:

A      B
a1     b0, b1, b1
a2     b2, b3
a3     b4, b4, b5, b5

Postgres是否有一个简单的A B a1 b0, b1 a2 b2, b3 a3 b4, b5 来做到这一点?

3 个答案:

答案 0 :(得分:2)

有两种方法可以实现此目的:

在删除重复项的同时取消嵌套元素并将其聚合回来的UPDATE语句:

  Set Dest = Workbooks("Master.xlsm").Worksheets(1)
  colDest = Dest.Cells(1, Dest.Columns.Count).End(xlToLeft).Column + 1
  wb.Worksheets(1).Range("b3:u83").Copy
  Dest.Cells(1, colDest).PasteSpecial Paste:=xlPasteValues

如果您需要经常执行此操作,另一种选择是创建一个删除重复项的函数并在UPDATE中使用它:

update bad_design
  set b = t.b
from (
  select a, string_agg(distinct trim(t.w), ',') b
  from bad_design
    cross join unnest(string_to_array(b, ',')) as t(w)
  group by a
) t
where t.a = bad_design.a;

然后您可以像这样使用它:

create or replace function cleanup(p_list text)
  returns text
as
$$
  select string_agg(distinct trim(t.w), ',')
  from unnest(string_to_array(p_list, ',')) as t(w);
$$
language SQL;

之所以如此复杂,是因为您没有正确规范化数据模型。使用正确归一化的模型,您可以简单地创建一个UNIQUE索引,并避免将重复项插入第一位。

答案 1 :(得分:1)

具体的更新语句取决于列b的类型,但实际上只有3种不同的方式可以以分隔字符串,文本数组或json的形式存储此数据

以逗号分隔的文本字段的更新语句为:

update mytable
set b = array_to_string(array(select distinct unnest(string_to_array(b, ', '))), ', ');

如果b是文本数组,则:

update mytable
set b = array(select distinct unnest(b));

如果b是一个json数组,则:

update mytable
set b = array_to_json(array(select distinct value from json_array_elements_text(b)));

如您所见,最干净语句是将数据存储为文本数组的情况下的结果。如果必须将值数组存储在1列中,请使用数组类型进行操作。

但是,我还建议规范化您的数据。

上面的这些语句将更新表中的所有行,因此产生更高的执行成本。我将说明一种使用文本数组变体减少更新的方法(因为这需要最短的sql查询):

update mytable
set b = array(select distinct unnest(b))
where array_length(b_array, 1) != (select count(distinct c) from unnest(b) c);

答案 2 :(得分:0)

假设:当前版本的Postgres,var data = [ [ {idStatus: 2, value: '120'}, {idStatus: 3, value: '130'}, {idStatus: 4, value: '140'}, {idStatus: 5, value: '150'} ], [ {idStatus: 1, value: '160'}, {idStatus: 2, value: '180'}, {idStatus: 4, value: '10'}, {idStatus: 5, value: '20'} ], [ {idStatus: 3, value: '567'}, {idStatus: 6, value: '234'}, {idStatus: 9, value: '747'}, {idStatus: 7, value: '789'} ], [ {idStatus: 8, value: '340'}, {idStatus: 5, value: '560'}, {idStatus: 6, value: '120'}, {idStatus: 2, value: '100'} ], [ {idStatus: 1, value: '106'}, {idStatus: 5, value: '345'}, {idStatus: 7, value: '756'}, {idStatus: 9, value: '946'} ] ] function getNewArray() { //convert string to int return data.map(item => item.map(v => parseInt(v.value))) } let newArray = getNewArray(); console.log(newArray); console.log(JSON.stringify(newArray)); 的数据类型为B,列表中的分隔符为text,删除所有 重复项,保留原始顺序元素,大多数或所有行都重复:

这应该是最简单,最快的:

', '

缺点:所有行都会更新,即使没有任何变化。如果影响多于几行,则可以避免...

如果没有任何假设,则可能会有其他/更好/更快的解决方案。

相关: