我有一个无聊的问题要解决(希望这对我来说很难哈哈),如下:
我有一个包含许多表的PostgreSQL数据库。 这些表每天都由Perl脚本更新。 对我的问题感兴趣的表遵循以下模式:
ID | Central | ts | Country | Name | Column3 | Column4 | Column5 |
------------------------------------------------------------------------------------------
没有唯一的列主键标识行unicaly ... 相反,我可以在使用“ID-Central-ts”构建的Perl脚本中看到BTree作为PK。 “ts”是脚本生成的时间戳,DB中总有3个ts,因此它存储过去3天的每个“中心ID”行。
所以,我想要的: 放开“Country”和“Name”列(即使在相同的ID-central-ts中这些列也可能没有问题,甚至重复自己),一个“ID-Central-ts”不应该有不同的列'值那些在特定中心显示的。 我需要一个查询,向我显示这些值与右中心不匹配的最新时间戳添加(最大数字)。
我的意思是: 如果对于ID 01,“default-central”表示“column3”,“column4”和“column5”的值必须是最后一个“ts”中带有“right”的字符串,则应捕获任何不同的值。示例:
假设Central'Alfa'是“默认中心”。 对于给定的ID,它存储的值必须等于此或任何其他Central中的每个“ID”。
ID | Central | ts | Country | Name | Column3 | Column4 | Column5 |
------------------------------------------------------------------------------------------
01 | Alfa | 10000001 | USA | Fairy | right | right | right |
01 | Alfa | 10000002 | USA | Minish | right | right | right |
01 | Alfa | 10000003 | USA | Elf | right | right | right |
01 | Delta | 10000001 | USA | Goron | right | right | right |
01 | Delta | 10000002 | USA | Elf | right | wrong | right |
01 | Delta | 10000003 | USA | Acqua | wrong | right | right |
.
.
.
02 | Alfa | 10000001 | BRA | Fairy | RIGHT | RIGHT | RIGHT |
02 | Alfa | 10000002 | BRA | Minish | RIGHT | RIGHT | RIGHT |
02 | Alfa | 10000003 | BRA | Elf | RIGHT | RIGHT | RIGHT |
02 | Delta | 10000001 | BRA | Goron | WRONG | RIGHT | RIGHT |
02 | Delta | 10000002 | BRA | Elf | RIGHT | WRONG | RIGHT |
02 | Delta | 10000003 | BRA | Acqua | WRONG | RIGHT | (null) |
我需要得到:
ID | Central | ts | Country | Name | Column3 | Column4 | Column5 |
-------------------------------------------------------------------------------------------
01 | Delta | 10000003 | USA | Acqua | wrong | | |
02 | Delta | 10000003 | BRA | Acqua | WRONG | | "Wrong null" |
即使ts 10000001或10000002的值不正确,也会看到它们没有被接收。 还要注意,当有空值应该存在一些值时,我需要写一些东西来表明这个null不应该存在。
任何人都可以看看吗? 我已经设法创建了一个视图来获取来自Alfa中心的值,但是我无法想象LEFT JOIN或者创建这些编写“错误null”事物的规则的方法,或者如何忽略较低的ts。
任何帮助都将受到高度赞赏。
答案 0 :(得分:1)
我将采取的方式是自我加入:
SELECT t.*
FROM theTable AS m -- values from the "master" central
INNER JOIN theTable AS t -- values from the central to test
ON m.Central = 'ALFA'
AND m.ts = (SELECT MAX(ts) FROM theTable)
AND m.ID = t.ID
AND m.ts = t.ts
AND t.Central <> m.Central
AND (
-- we assume that values in the "master" central cannot be null or blank
m.Column3 <> coalesce(t.Column3, '') OR
m.Column4 <> coalesce(t.Column4, '') OR
m.Column5 <> coalesce(t.Column5, '')
)
在这种情况下,你也可以使用CTE,有些人会发现它们更具可读性:
WITH MaxTimestamp AS (
SELECT MAX(tx) value FROM theTable
),
MasterValues AS (
SELECT * FROM theTable WHERE Central = 'ALFA' AND ts = (SELECT value FROM MaxTimestamp)
),
TestValues AS (
SELECT * FROM theTable WHERE Central <> 'ALFA' AND ts = (SELECT value FROM MaxTimestamp)
)
SELECT t.*
FROM MasterValues m
INNER JOIN TestValues t
ON m.ID = t.ID
AND (
-- we assume that values in the "master" central cannot be null or blank
m.Column3 <> coalesce(t.Column3, '') OR
m.Column4 <> coalesce(t.Column4, '') OR
m.Column5 <> coalesce(t.Column5, '')
)
在任何一种情况下,您也可以将整个事物写为函数或匿名块,这样您就可以将主中心的值指定为参数或变量,以防不是固定值。
答案 1 :(得分:0)
应该是
select
ID
,Central
,ts
,Country
,name
,COALESCE(column3, 'wrong') AS Column3
,COALESCE(column4, 'wrong') AS Column4
,COALESCE(column5, 'wrong') AS Column5
FROM T1
WHERE
(UPPER(Column3) <> 'RIGHT' OR UPPER(Column4) <> 'RIGHT' OR UPPER(Column5) <> 'RIGHT')
and ts = (SELECT MAX(ts) FROM T1)
答案 2 :(得分:0)
我得到了LEFT JOIN的答案,其中包括我想要的每一个案例。
非常感谢每一条建议,并且对不接受我之前提出的任何答案感到遗憾...... 也许我还没有完全清楚,但我的答案提出了对我的问题的确切回应。
我不会更改查询以适应我以前用过的列名,因为我担心我会弄错。 我没有创建大量的AND,而是决定逐列获取每个差异,然后在FULL OUTER JOIN中加入它们的所有差异。
按照我的第一个查询,获取与给定中心不同的值。
SELECT Test_Configs.central, Test_Configs.imsi,
CASE Test_Configs.mapver WHEN '' THEN '-'
ELSE COALESCE(Test_Configs.mapver, '-')
END
FROM config_imsis_centrais AS Default_Configs -- Valores padrão da central correta
LEFT JOIN config_imsis_centrais AS Test_Configs -- Valores das centrais a serem testadas
ON Default_Configs.central = 'CENTRAL_USED_AS_EXAMPLE'
AND Default_Configs.ts = (SELECT MAX(ts) FROM config_imsis_centrais)
AND Default_Configs.imsi = Test_Configs.imsi
AND Default_Configs.ts = Test_Configs.ts
AND Test_Configs.central <> Default_Configs.central
WHERE ( -- Análise:
COALESCE(Default_Configs.mapver, 'null') <> COALESCE(Test_Configs.mapver, 'null') AND
Test_Configs.central <> ''
)
我的全部加入加入是通过加入每个潜在表格,使用中心和“imsi”,(就像我的例子中的ID一样)。如下:
SELECT central, imsi, mapver, camel, nrrg
FROM
vw_erros_mgisp_mapver
FULL OUTER JOIN
vw_erros_mgisp_camel USING (central, imsi)
FULL OUTER JOIN
vw_erros_mgisp_nrrg USING (central, imsi)
ORDER BY central, imsi
就是这样。非常感谢大家,不好意思不接受你努力工作的答案,我认为对于有同样问题的人研究更好的解决方案会更好。
干杯!