Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何返回数据库中现有表中某一行的特定列值?_Sql_Postgresql_Foreign Keys_Case_Case When - Fatal编程技术网

Sql 如何返回数据库中现有表中某一行的特定列值?

Sql 如何返回数据库中现有表中某一行的特定列值?,sql,postgresql,foreign-keys,case,case-when,Sql,Postgresql,Foreign Keys,Case,Case When,问题: 我在PostgreSQL 9.0中工作,我很难弄清楚如何处理需要返回某行的特定列值以用于CASE WHEN THEN语句的情况 我想基本上进入并设置表A:someRow的someColumn值,等于表B:row X的column A值,给定row X的column B的值。(如果需要了解问题,请参阅“背景信息”中的更多详细信息) 这就是我想做的(但不知道怎么做): 背景信息:(可选,用于澄清) 假设在已经存在的数据库中有一个用户活动表和一个设备表,其中包含已经存在的活动执行字符串,这些字

问题:

我在PostgreSQL 9.0中工作,我很难弄清楚如何处理需要返回某行的特定列值以用于CASE WHEN THEN语句的情况

我想基本上进入并设置表A:someRow的someColumn值,等于表B:row X的column A值,给定row X的column B的值。(如果需要了解问题,请参阅“背景信息”中的更多详细信息)

这就是我想做的(但不知道怎么做):

背景信息:(可选,用于澄清)

假设在已经存在的数据库中有一个用户活动表和一个设备表,其中包含已经存在的活动执行字符串,这些字符串一直存在于您正在使用的代码库中:(例如)

老板的任务是创建一个报告,其中显示一个包含所有设备活动的表,如下所示:

Device Activity Report
(int)     (int)    (string)       (string)                                 (string)      (int)         (string)
act_seq  |usr_id | usr_name     | act_performed                         |  dvc_name | dvc_srl_num | dvc_status  
---------+-------+--------------+---------------------------------------+-----------+-------------+------------
1        |1      | Joe Martinez | Checked out iphone: iphone2           | iphone2   | 12345       | checked out 
2        |2      | John Shmoe   | uploads video from device: (id: 12345)| android1  | 23456       | available    
出于这个问题的目的,必须通过向名为dvc_seq的用户活动表添加一个新列来完成,该列将是设备表的外键。您将通过从用户活动表查询并连接两个where user_activity(dvc_seq)=Device(seq)来创建一个临时表

这很好,对于用户活动表中的新条目非常有用,如果活动涉及设备,用户活动表将记录链接到相关设备的dvc seq

问题是,您需要在User_Activity表中的新dvc_seq列中填入与设备相关的所有以前条目的值。由于之前的程序员决定在activity_performed(活动_执行)列中指定特定时间使用序列号而其他时间使用设备名称的设备,因此这提出了一个有趣的问题,您需要从给定设备名称或序列号的设备中导出关联的设备序列号

再一次,我想做的是:(使用这个例子)


你们谁能帮我完成这个任务??提前感谢所有回复和建议

在postgresql中,您不能像

CASE WHEN activity_performed LIKE 'checked out iphone:%' 
只有

您最多只能创建一个函数

UPDATE User_Activity 
SET dvc_seq = getDeviceID(User_Activity.activity_preformed);
在这里你可以做,如果情况更容易

CREATE OR REPLACE FUNCTION getDeviceID(activity text)
RETURNS integer AS
$BODY$
DECLARE 
    device_name text;
    device_id   integer;

BEGIN
    -- parse the string activity 

    /* this part is pseudo code
    set device_id;
    IF (device_id is null)
       set device_name;
       search for device_id using device_name;
       set device_id;
    */
    RETURN device_id;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION get_box(text)
  OWNER TO postgres;

当序列号或名称包含在执行的活动中时,下面的查询使用更新联接来更新序列号

UPDATE UserActivity
SET a.dvc_seq = b.seq
FROM UserActivity AS a
JOIN devices b 
    ON UserActivity.activity_performed LIKE '%from device: (id: ' || b.serial_num || '%'
    OR UserActivity.activity_performed LIKE '%: ' || b.name || '%'

根据@FuzzyTree给出的正确答案,只需对如何加速此代码进行额外更新(这只适用于具有标准长度的序列号,而不适用于可能有许多不同大小的设备名称)

由于联接中使用了类似的方法,因此对于大型数据库,查询运行速度非常慢。更好的解决方案是利用postgres
substring()
position()
函数,并按如下方式连接序列号上的表:

UPDATE UserActivity
SET a.dvc_seq = b.seq
FROM UserActivity AS a
JOIN devices b 
    ON b.serial_num = 
    substring(activity_performed from position('%from device: (id: ' in activity_performed)+(length of the string before the plus so that position returns the start position for the serial number)) for (lengthOfSerialNumberHere)) 
WHERE UserActivity.activity_performed LIKE '%from device: (id: ' || b.serial_num || '%';`

我不确定我是否想帮你教我的Iphone跟踪我的卫生间休息时间,但是你能用你的数据创建一个新的记录吗?这会有很大帮助。要做到这一点,我们需要知道如何解析您的
活动执行的
列。我们是否可以检查char
的第一次出现,并尝试查看是否有和
id
或之后是否有
设备名称
?或者,
dvc\u name
column可以有空间吗?@JuanCarlosOropeza老实说,我还没有给那个部分太多的空间。
dvc\u名称
可以有空格,例如,
“android 3”
将是一个有效的条目。肯定要像你说的那样解析那个字符串,但现在我更关心的是如何返回特定行的列值。无论您如何解析它,返回特定行的列值应该是相同的,对吗?如果没有您所拥有的详细示例,我无法帮助您。我只能给你一般的指导方针。如果您需要我回答中的伪代码的帮助,请告诉我。我考虑过这一点,但可能
b.serial\u num
b.name
会出现在
a.activity\u执行的
的其他部分,而不是deviceID@JuanCarlosOropeza我添加了一些前缀以降低出错的可能性positives@FuzzyTree谢谢你的帮助,这是我得到的最接近的查询,但仍然给我带来问题。。。测试此查询时,它会更新用户活动表中的每个条目,而不仅仅是Activity_执行的条目看起来像代码中的两个字符串。每个条目也会被相同的dvc序列号填充。有什么想法吗?
dvc\u seq
名称和
序列号是什么?它们中有一个是空的吗?更新:我通过在末尾添加一个额外的WHERE子句来实现它,例如:
WHERE UserActivity.activity\u的执行方式与设备中的“%from”:(id:“|| b.serial_num | |“%”或UserActivity.activity|u的执行方式类似“%”:“:”| b.name | |“%”
再次感谢@FuzzyTree,我将此答案标记为解决问题的答案。
UPDATE User_Activity 
SET dvc_seq = getDeviceID(User_Activity.activity_preformed);
CREATE OR REPLACE FUNCTION getDeviceID(activity text)
RETURNS integer AS
$BODY$
DECLARE 
    device_name text;
    device_id   integer;

BEGIN
    -- parse the string activity 

    /* this part is pseudo code
    set device_id;
    IF (device_id is null)
       set device_name;
       search for device_id using device_name;
       set device_id;
    */
    RETURN device_id;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION get_box(text)
  OWNER TO postgres;
UPDATE UserActivity
SET a.dvc_seq = b.seq
FROM UserActivity AS a
JOIN devices b 
    ON UserActivity.activity_performed LIKE '%from device: (id: ' || b.serial_num || '%'
    OR UserActivity.activity_performed LIKE '%: ' || b.name || '%'
UPDATE UserActivity
SET a.dvc_seq = b.seq
FROM UserActivity AS a
JOIN devices b 
    ON b.serial_num = 
    substring(activity_performed from position('%from device: (id: ' in activity_performed)+(length of the string before the plus so that position returns the start position for the serial number)) for (lengthOfSerialNumberHere)) 
WHERE UserActivity.activity_performed LIKE '%from device: (id: ' || b.serial_num || '%';`