Redshift 在多个条件下加入,但仅在一个条件不匹配时返回

Posted

技术标签:

【中文标题】Redshift 在多个条件下加入,但仅在一个条件不匹配时返回【英文标题】:Redshift Join on multiple conditions but return only where one condition doesn't match 【发布时间】:2021-11-03 16:28:53 【问题描述】:

我有两张表,第一张有 ID 和编号。 ID 和号码可能会列出不止一次。

我的第二个表再次包含 ID 和数字(以及其他数据)的行(1 亿)。我需要在该表中搜索任何 ID,其数字不在结果表中的数字列表中。

我在返回表 2 中与第一个限定符匹配但不匹配第二个限定符的任何记录的连接时遇到问题。

DROP TABLE IF EXISTS `myTable`;

CREATE TABLE `myTable` (
  `id` mediumint(8) unsigned NOT NULL auto_increment,
  `ID` varchar(255),
  `Numbers` mediumint default NULL,
  PRIMARY KEY (`id`)
) AUTO_INCREMENT=1;

INSERT INTO `myTable` (`ID`,`Numbers`)
VALUES
  ("CRQ44MPX1SZ",1890),
  ("UHO21QQY3TW",4370),
  ("JTQ62CBP6ER",1825),
  ("RFD95MLC2MI",5014),
  ("URZ04HGG2YQ",2859),
 ("CRQ44MPX1SZ",1891),
  ("UHO21QQY3TW",4371),
  ("JTQ62CBP6ER",1826),
  ("RFD95MLC2MI",5015),
  ("URZ04HGG2YQ",2860),
 ("CRQ44MPX1SZ",1892),
  ("UHO21QQY3TW",4372),
  ("JTQ62CBP6ER",1827),
  ("RFD95MLC2MI",5016),
  ("URZ04HGG2YQ",2861);



DROP TABLE IF EXISTS `myTable2`;

CREATE TABLE `myTable2` (
  `id` mediumint(8) unsigned NOT NULL auto_increment,
  `ID` varchar(255),
  `Numbers` mediumint default NULL,
  PRIMARY KEY (`id`)
) AUTO_INCREMENT=1;

INSERT INTO `myTable2` (`ID`,`Numbers`)
VALUES
  ("CRQ44MPX1SZ",1870),
  ("UHO21QQY3TW",4350),
  ("JTQ62CBP6ER",1825),
  ("RFD95MLC2MI",5014),
  ("URZ04HGG2YQ",2859),
 ("CRQ44MPX1SZ",1891),
  ("UHO21QQY3TW",4371),
  ("JTQ62CBP6ER",1826),
  ("RFD95MLC2MI",5015),
  ("URZ04HGG2YQ",2860),
 ("CRQ44MPX1SZ",1882),
  ("UHO21QQY3TW",4372),
  ("JTQ62CBP6ER",1827),
  ("RFD95MLC2MI",5016),
  ("URZ04HGG2YQ",2861);

SELECT mytable1.ID, listagg(distinct mytable2.Numbers, ',') as unauth_list, count(mytable2.Numbers) as unauth_count
FROM mytable1
LEFT JOIN mytable2 on mytable1.id = mytable2.id
WHERE (mytable1.id = mytable2.id)
AND (mytable1.Numbers <> mytable2.Numbers)
GROUP BY mytable1.id

预期输出:

(“CRQ44MPX1SZ”, ”1870,1882”, 2)
(“UHO21QQY3TW”, ”4350”, 1)

【问题讨论】:

【参考方案1】:

史蒂夫。你很亲密。您需要在 FROM 子句中反转您的表(或使用 RIGHT JOIN)并添加一个 JOIN ON 子句。 WHERE 子句现在将基于在表 1 的 Numbers 中看到 NULL。使用您的数据设置试试这个:

SELECT mytable2.ID, listagg(distinct mytable2.Numbers::text, ',') as unauth_list, count(mytable2.Numbers) as unauth_count
FROM mytable2
LEFT JOIN mytable1 on mytable1.id = mytable2.id 
and mytable1.numbers = mytable2.numbers
Where mytable1.Numbers is null
GROUP BY mytable2.id;

见小提琴 - http://sqlfiddle.com/#!15/44b5e/4

产生结果:

id  unauth_list unauth_count
CRQ44MPX1SZ 1870,1882   2
UHO21QQY3TW 4350    1

SF 想让我重复你的数据设置,所以

CREATE TABLE myTable1 (
  ID varchar(255),
  Numbers int default NULL
) ;

INSERT INTO myTable1 (ID,Numbers)
VALUES
  ('CRQ44MPX1SZ',1890),
  ('UHO21QQY3TW',4370),
  ('JTQ62CBP6ER',1825),
  ('RFD95MLC2MI',5014),
  ('URZ04HGG2YQ',2859),
 ('CRQ44MPX1SZ',1891),
  ('UHO21QQY3TW',4371),
  ('JTQ62CBP6ER',1826),
  ('RFD95MLC2MI',5015),
  ('URZ04HGG2YQ',2860),
 ('CRQ44MPX1SZ',1892),
  ('UHO21QQY3TW',4372),
  ('JTQ62CBP6ER',1827),
  ('RFD95MLC2MI',5016),
  ('URZ04HGG2YQ',2861);


CREATE TABLE myTable2 (
  ID varchar(255),
  Numbers int default NULL
) ;

INSERT INTO myTable2 (ID,Numbers)
VALUES
  ('CRQ44MPX1SZ',1870),
  ('UHO21QQY3TW',4350),
  ('JTQ62CBP6ER',1825),
  ('RFD95MLC2MI',5014),
  ('URZ04HGG2YQ',2859),
 ('CRQ44MPX1SZ',1891),
  ('UHO21QQY3TW',4371),
  ('JTQ62CBP6ER',1826),
  ('RFD95MLC2MI',5015),
  ('URZ04HGG2YQ',2860),
 ('CRQ44MPX1SZ',1882),
  ('UHO21QQY3TW',4372),
  ('JTQ62CBP6ER',1827),
  ('RFD95MLC2MI',5016),
  ('URZ04HGG2YQ',2861);

【讨论】:

感谢您的帮助!我仍在解决这个问题,因为我能够发现第二个表中存在第一个表中不存在的 ID 的问题。所以现在我正在努力解决这个问题并为这些案例生成一个计数。 对于 Redshift,我建议您将表 1 与表 2 连接起来,并检查表 1 中的空 ID。这通常是在 Redshift vs. WHERE NOT EXISTS 中执行此操作的最佳方法

以上是关于Redshift 在多个条件下加入,但仅在一个条件不匹配时返回的主要内容,如果未能解决你的问题,请参考以下文章

删除括号之间的文本,但仅在给定条件下

仅在某些条件下使用 Redshift 中的 SQL 对具有相同名称的行进行分组

Mongoose:批量更新插入,但仅在满足某些条件时才更新记录

仅在满足条件时链接多个 CompletionStage

有没有办法在 Redshift Spectrum 中使用“IN”条件检查多个列?

mysqldump整个结构,但仅在单个命令中选择表中的数据