sql - 根据条件将B表中的行添加到A表中

标签 sql database python-3.x sqlite

我正在使用 python 和 sqlite。我有两个数据表,表 A 和表 B。我想在以下条件下将表 B 与表 A 的行连接起来:

  • 如果某行出现在 B 而不是 A 中,则将其添加到 A。
  • 如果某行在 B 中出现的次数多于在 A 中出现的次数,则将其添加到 A 中,直到它在 A 中出现的次数与在 B 中出现的次数一样多。

如果我有以下两张表

Table A  Table B
2 4 1 3  2 2 2 1
2 2 2 1  2 4 1 3
4 5 2 4  2 4 1 3
1 4 2 5  2 4 1 3
2 4 1 3  5 3 2 3

我想要下表

Table A + B
  2 2 2 1
  2 4 1 3
  2 4 1 3
  2 4 1 3
  4 5 2 4
  1 4 2 5
  5 3 2 3

问题:是否可以通过 sql 查询来实现此目的?如果是这样;怎么办?

编辑:虽然事实证明答案非常有帮助,但它们并不能解决整个问题。

SELECT valB1, valB2, valB3, valB4 FROM B
WHERE NOT EXISTS(SELECT valA1, valA2, valA3, valA4
             FROM A
             WHERE A.valA1 = B.valB1
               AND A.valA2 = B.valB2
               AND A.valA3 = B.valB3
               AND A.valA4 = B.valB4)

将返回不在 A 中但在 B 中的行。如果一行在 B 中出现 3 次而在 A 中仅出现 2 次,则不会返回该行的一个实例,而这正是我需要的增加表 A 中该行的出现次数。

查询

SELECT col1, col2, col3, col4
FROM TableA
EXCEPT
SELECT col1, col2, col3, col4
FROM TableB
UNION ALL
SELECT col1, col2, col3, col4
FROM TableB

不起作用,因为如果 B 中的行少于 A 中的行,我最终会得到 B 中该行的数量,而不是 A 中的行数量。 谢谢!

最佳答案

相同的列,并将它们拼接在一个结果集中?

听起来像 UNION ALLEXCEPT可以在这里使用。

SELECT col1, col2, col3, col4
FROM TableA
EXCEPT
SELECT col1, col2, col3, col4
FROM TableB
UNION ALL
SELECT col1, col2, col3, col4
FROM TableB

db<>fiddle here 上进行测试

但它有一个缺点,即会导致 TableB 中出现大量重复行。

如果您能够使用最终支持窗口函数的 Sqlite 版本(3.25+)? Reference 。那么使用ROW_NUMBER就可以解决“重复表A>重复表B”的问题:

SELECT col1, col2, col3, col4
FROM
(
  SELECT col1, col2, col3, col4, 
    row_number() over (partition by col1, col2, col3, col4 order by (select 0)) as rn
  FROM TableA 
  EXCEPT 
  SELECT col1, col2, col3, col4, 
    row_number() over (partition by col1, col2, col3, col4 order by (select 0))
  FROM TableB 
  UNION ALL 
  SELECT col1, col2, col3, col4, 0
  FROM TableB
) q
ORDER BY col1, col2, col3, col4

test

在旧版本中,可以模仿 ROW_NUMBER 窗口函数。

SELECT col1, col2, col3, col4
FROM
(
  SELECT a.col1, a.col2, a.col3, a.col4,
  (select count(*) from TableA a2
   where a2.col1 = a.col1 
     and a2.col2 = a.col2 
     and a2.col3 = a.col3 
     and a2.col4 = a.col4
     and a2.rowid >= a.rowid) as rn
  FROM TableA a
  EXCEPT
  SELECT b.col1, b.col2, b.col3, b.col4,
  (select count(*) from TableB b2
   where b2.col1 = b.col1 
     and b2.col2 = b.col2 
     and b2.col3 = b.col3 
     and b2.col4 = b.col4
     and b2.rowid >= b.rowid)
  FROM TableB b
  UNION ALL
  SELECT col1, col2, col3, col4, 0
  FROM TableB
) q
ORDER BY col1, col2, col3, col4

db<>fiddle here 上进行测试

关于sql - 根据条件将B表中的行添加到A表中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52247962/

相关文章:

mysql - WHERE 子句中的 SELECT 语句之一

python - 选择四张牌并检查它们的总和是否为 24 - Python

python - 如何区分计算器的运算符和负数?

mysql - 如何创建 SQL 查询来获取比较两列具有更高值的所有项目

mysql - 将频繁更新的列移至单独的表以获得更好的性能?

database - 在数据库列中存储分隔列表真的那么糟糕吗?

mysql - 更新mysql中的余额

python - 从右到左和从左到右打印得很好

mysql - 优化此 sql 查询的最佳方法是什么

php - SQL 查询 - 在一个结果行中显示连接结果