【问题标题】:How can I join tables using information from different rows?如何使用来自不同行的信息连接表?
【发布时间】:2021-12-07 09:17:27
【问题描述】:

我有两个相似的表格想要加入。请参阅下面的可重现示例。

需要做什么

查看代码中的 cmets:连接值 '2021-01-01'(列:日期)、'hat'(列:内容)、'cat'(列:内容)和 'A'(列:Tote)在 first_table 中将产生一个唯一键,该键可以与 second_table 中完全相同的数据连接。结果将是 4 个唯一事件的第一行(请参阅 desired_result: '#first tote')。实际上,行数将是几百万。

可重现的例子:

CREATE OR REPLACE TABLE
`first_table` (
  `Date` string NOT NULL,
  `TotearrivalTimestamp` string  NOT NULL,
  `Tote` string NOT NULL,
  `content` string NOT NULL,
  `location` string NOT NULL,
);
INSERT INTO `first_table` (`Date`, `TotearrivalTimestamp`, `Tote`, `content`, `location`) VALUES
  ('2021-01-01', '13:00','A','hat','1'), #first tote
  ('2021-01-01', '13:00','A','cat','1'), #first tote
  ('2021-01-01', '14:00', 'B', 'toy', '1'),
  ('2021-01-01', '14:00', 'B', 'cat', '1'),
  ('2021-01-01', '15:00', 'A', 'toy', '1'),
  ('2021-01-01', '13:00', 'A', 'toy', '1'),
  ('2021-01-02', '13:00', 'A', 'hat', '1'),
  ('2021-01-02', '13:00', 'A', 'cat', '1');
  
CREATE OR REPLACE TABLE
`second_table` (
  `Date` string NOT NULL,
  `ToteendingTimestamp` string  NOT NULL,
  `Tote` string NOT NULL,
  `content` string NOT NULL,
  `location` string NOT NULL,
);
INSERT INTO `second_table` (`Date`, `ToteendingTimestamp`, `Tote`, `content`, `location`) VALUES
('2021-01-01', '20:00', 'B', 'cat', '2'),
('2021-01-01', '19:00', 'A', 'cat', '1'), #first tote
('2021-01-01', '19:00', 'A', 'hat', '1'), #first tote
('2021-01-01', '20:00', 'B', 'toy', '2'),
('2021-01-01', '14:00', 'A', 'toy', '1'),
('2021-01-02', '14:00', 'A', 'hat', '1'),
('2021-01-02', '14:00', 'A', 'cat', '1'),
('2021-01-01', '16:00', 'A', 'toy', '1');

CREATE OR REPLACE TABLE
`desired_result` (
  `Date` string NOT NULL,
  `Tote` string NOT NULL,
  `TotearrivalTimestamp` string  NOT NULL,
  `ToteendingTimestamp` string  NOT NULL,
  `location_first_table` string NOT NULL,
  `location_second_table` string NOT NULL,
 );
INSERT INTO `desired_result` (`Date`, `Tote`, `TotearrivalTimestamp`, `ToteendingTimestamp`, `location_first_table`, `location_second_table`) VALUES

('2021-01-01', 'A', '13:00', '19:00', '1', '1'), #first tote
('2021-01-01', 'B', '14:00', '20:00', '1', '1'),
('2021-01-01', 'A', '15:00', '16:00', '1', '2'),
('2021-01-02', 'A', '13:00', '14:00', '1', '1');


#### this does not give what I want####
select first.date as Date, first.tote, first.totearrivaltimestamp, second.toteendingtimestamp, first.location as location_first_table, second.location as location_second_table
from `first_table` first 
inner join `second_table` second 
on first.tote = second.tote 
and first.content = second.content;

【问题讨论】:

  • 对于所需的输出如何成为输入的函数没有明确的描述。 “基于”和“结合”没有告诉我们任何信息,也没有列出可能涉及的运营商。 minimal reproducible example 使用足够多的单词、句子和对部分示例的引用来清楚完整地表达你的意思。在给出业务关系(船)/关联或表(基础或查询结果)时,说明其中的一行根据其列值说明了业务情况。 PS 既然您将输入作为表格代码(好),您不需要早期的冗余(可能是错误的)版本。
  • 请根据我最后的评论采取行动。没有人可以接受您所写的内容并知道要写什么查询。他们只能猜测。 PS 句子片段标记行不是“使用足够的单词、句子和对部分示例的引用来清楚完整地表达你的意思。”
  • 好的,感谢您的支持。现在清楚了吗?

标签: sql join group-by google-bigquery


【解决方案1】:

我能够使用下面的 SQL 重现“desired_result”表(大部分情况下)。我相信“插入”语句存在一些错别字。但是,我认为这符合意图。

查询:

select  
first_table.date as Date, 
first_table.tote, 
first_table.totearrivaltimestamp, 
second_table.toteendingtimestamp, 
first_table.location as location_first_table, 
second_table.location as location_second_table
from first_table
inner join `second_table` 
on first_table.Date = second_table.Date 
and first_table.tote = second_table.tote
group by first_table.Date, first_table.TotearrivalTimestamp, first_table.tote;

结果:

2021-01-01|A|13:00|19:00|1|1
2021-01-01|B|14:00|20:00|1|2
2021-01-01|A|15:00|19:00|1|1
2021-01-02|A|13:00|14:00|1|1

此结果假定您的第一个餐桌日期始终与手提袋/时间戳匹配。然后 group by 函数合并重复的结果。第二个表信息与第一个表的日期和手提箱匹配,并附加到行项目。

【讨论】:

  • 强烈建议不要使用纯代码的答案。请edit your answer 解释代码如何/为什么解决问题。 - From Review
  • 感谢您调整其他答案,但请考虑我自己的可重现示例。
【解决方案2】:

这个答案应该有效。我认为您的问题可能与您对表格的某些引用有关....

select f.'date'
,f.tote
, f.totearrivaltimestamp
, s.toteendingtimestamp
, f.location as location_first_table
, s.location as location_second_table
from first f
,INNER JOIN "second" s on f.'date' = s.'date'
and f.tote = s.tote 
and f.content = s.content

【讨论】:

  • 语法错误。 (选择显式 JOIN 语法。)
  • 不可能...测试它所花费的时间是您构建它所花费的时间的 10 倍,所以请耐心等待...
  • 啊,我知道有一个错误的沟通......我想加入所有的手提包。最后一行只是一个例子!让我改一下
  • 所以我想加入 Totes。例如:第一个 Tote 将使用“2021-01-01”(日期)、“hat”(内容)、“cat”(内容)和“A”(Tote)来连接。
  • 我看不到任何支持from first f ,(INNER JOIN second 的dbms。 正在使用哪些 dbms? “日期”和“秒”是处理用作标识符的保留字的方式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-22
  • 1970-01-01
  • 1970-01-01
  • 2013-09-07
  • 2021-12-03
相关资源
最近更新 更多