Total Pageviews

2018/07/02

[閱讀筆記] The Four Pillars of Investing (7/12)


  1. 科技進步會帶動經濟成長,進而帶動股價攀升。如果突然出現一種邪惡力量讓所有科技創新頓然停止,那麼我們的生活水準將凍結在現有的水準,企業營利則將維持不變,至於股價即便還是會繼續波動,也很難出現長期漲勢。這是極為重要的關鍵:股市報酬的動力來自於科技成長的相對速率,而非絕對水準
  2. 最豐厚的報酬往往不會落入發明人的口袋
  3. JP Morgan已掌握並證明,投資新興科技產業的報酬少的可憐,因此在投資時盡可能避免投資出現時機不對的公司
  4. 購買 IPO 的報酬根本不夠塞牙縫,投資者對於新創科技公司都抱持過度樂觀的態度
  5. 上升的股價自有其生命週期,而泡沫亦隨後發生
  6. 再也沒有什麼事比眼看好友致富更會讓人錯亂跟失去判斷力了
  7. 經濟泡沫出現的必要條件包括:
    1. 科技革命或財務方法的重大轉移
    2. 資金的流動性,即信用便於取得
    3. 泡沫傷痕失憶症,這通常需要花上一整個世代的時間
    4. 放棄歷來著名的證券評估方式,通常導因於市場被投資生手所接管
  8. 只要當投資者開始因為股價上漲就開始追進股票,經濟泡沫就已開始成長。這是個自我蠶食的過程,就像是露營的營火,要到燃料耗盡,才會熄滅
  9. 泡沫經濟的本質:股價在短期內急遽攀高,接著就是漫長的懷疑期,這讓投資者願意以極高的價格與極低的貼現率來購買可疑公司的股票。在泡沫裡,投資天堂一閃而過,留下的只剩斷垣殘壁與夢想破滅,不分階級或學識高低,都得共嚐苦果
  10. 對於泡沫經濟,牛頓曾說過:我可以精準計算物體的運動,卻無法衡量人們的瘋狂
  11. 即使某種發明足以帶來深刻而長遠的進步與繁榮,真正獲利的人也只不過是極少數的幸運兒,對於後到的投資人來說,已經是片無利可圖的廢墟
  12. 創新科技投資領域裡的另外一個模式:真正獲益的人是使用者,而非製造者。長期而言,運河經營者獲利的程度遠遠不及利用全新運輸方法從事商業活動的使用者
  13. 不管是怎樣的投資組合,報酬和市場相當,但風險高於市場的話,這種投資組合絕非首選
  14. 投資者必須理性地面對不理性的榮景,也必須有能力處理似乎無所不在的憂鬱情緒
  15. 過去報酬的豐厚程度會與未來報酬成反比,這其實是相當簡單的數學問題。一般來說,買到的股價太高並非好事。如果預期報酬太低,那麼統計機率告訴我們,股價未來相當可能繼續下探
  16. 不要低估堅守信仰所需要的勇氣,人類本來就是社會動物,要買進別人避之惟恐不及的資產,更需要堅忍不拔的毅力,其間的甘苦絕非一般投資者所能想像。但如果你真能做到這一點,未來的報酬必然十分甜美
  17. 投資行為是一種經過徹底分析以獲致高度安全與豐厚報酬的舉動。無法符合這些標準的作法都應報以懷疑態度
  18. 無論任何股票,在本質上都無好壞之分。如果價格太高,就算是好公司也很危險;如果價格夠低,再怎麼爛的公司也有可能是個好投資
  19. Graham 建議,就算是最保守的投資人也應該在投資組合中保持 25% 的股票;至於最積極的投資人則不應該超過 75%。這意味著一般投資人應該保持股票和債券比例各半的投資方式
  20. 嚴苛的熊市只不過是生命裡必然的歷程,而且無從避免熊市所帶來的效應。當景氣愈趨蕭條時,專業投資者還是穩如泰山,但業餘散戶就會丟掉手中的導覽藍圖,甚至很多人手上原本就沒有導覽圖

2018/07/01

[閱讀筆記] Thinking, Fast and Slow (4/9)


  1. 直覺是有效率且情緒化的,它可以加速決策效率,也會帶來 systematic and predictable errors
  2. 經驗判斷法的預測模式雖然較為簡單,但其預測結果的準確度與其他預測方法並無太大差異,更甚者有時還出現預測結果較為準確的情形,且具有省時省力且預測快速的優點,因此,經驗預測方法不可偏廢。人類在面對不確定的情況下,並以經驗預測法來對未來作判斷時,會因為人為的因素,而使預測結果產生偏誤,因此,在理論與實務的應用上,必須考量人類的心理因素,才能找出真正影響的原因。傳統經濟學的理論己無法完全描述現代社會的經濟現象,亦無法以傳統的經濟理論來解釋以經驗法來作預測時所產生的偏誤原因,因此,在分析人類的決策行為時,不宜將人類的心理因素抽離,故以經濟學為主而以心理學為輔的行為經濟學,其在整體經濟的分析過程中所扮演的角色也愈來愈重要
  3. 刻板印象是我們對人事物的看法,不牽涉喜歡不喜歡;偏見是我們對人事物的看法之後的感覺,會有喜歡及不喜歡的感受;歧視則是我們因為對人事物有某個看法而有某個感覺,因而依循其感覺行差異對待。
  4. 刻板印象是不可避免的,刻板印象可以讓我們在人際互動中快速替他人找出特點、分類,這可以協助我們有效率的做出一些決策,例如說,我今天新認識一個人,他穿汗衫短褲夾腳拖,我對這樣的人的刻板印象是「好似流浪漢」、「可能不注重外表整潔」,於是我心裡就會有一個對這個人的分類,這是我對此人的記憶方式,因此刻板印象可以讓我們不用花太多力氣就能把新訊息處理歸類好,所以為什麼刻板印象無法避免的原因便在此。
  5. 人們對事物的判斷力深受媒體的影響,媒體傾向報導一些新奇、吸引人注意與打動人心的事物。當媒體報導著龍捲風造成多少傷亡時,其實氣喘的致死率是龍捲風的 20 倍,可別誤會龍捲風的致死率比較高。新聞媒體不僅塑造了大眾的興趣,同時也被大眾的興趣所塑造
  6. 心理學家指出人類會有驗應性偏誤(confirmation bias),也就是比較會注意到自己所預期的事、而忽略自己沒預料到的事。而且就算我們已經注意到失敗的跡象,也很容易再落入情意捷思(affect heuristic),也就是因為相信某件事,所以自動在心中放大好消息、忽略壞消息。
  7. Heuristics (捷思),譬如定錨心理(anchoring)、可得性(availability)、代表性(representativeness),用直覺取代或然率分析和統計分析。短期來看,根據 heuristics 來進行投資的人可以得到很多樂趣;長期來看,根據統計來進行投資的人可以累積很多財富
  8. Availability cascade :是一種自我持續的連鎖事件,開始時可能是媒體報導的一件相當小的事,最後卻引起了大眾的恐慌和大規模的政府行動。有時候,一個媒體報導的小故事引起了某一群人的注意,他們變得激情和憂慮,而這種情緒反應本身又變成了報導的題材,引起了媒體更多的報導,然後引起了更多人的關心和參與。
  9. 代表性捷思法(representativeness Heuristics)指人們在不確定性的情形下,會抓住問題的某個特徵來直接推斷結果,而不考慮這種特徵出現的真實概率以及與特徵有關的其他原因。在很多情況下,代表性法則是一種非常有效的方法,能幫助人們迅速地抓住問題的本質推斷出結果,但有時也會造成嚴重的偏差,特別是會忽視事件的基本要素(base rate neglect),即無條件概率和樣本大小。
  10. 若 Steve 個性文靜、害羞,穿著乾乾淨淨,你認為他是個農夫或是圖書館管理員。若你因為從外表來判斷,很有可能判斷 Steve 應該會是位圖書館員。此時就犯了用 representativeness 來做為機率判斷的錯誤,你應該先關注 base rate,即根據農夫與圖書館管理員在此地區占的比率,再進行猜測,而非用外表來臆測
  11. 人是一種很奇特的動物,當面對沒有給予證據與給予無用的證據,前後竟然會有不同的行為。都沒有給你任何特定證據時,你反而還會基於 base rate 來做決定,當給你無效證據時,你卻會忽略 base rate,做出完全不同的決定
  12. 決策者對樣本大小缺乏敏感性 (insensitivity to sample size) 也是一種偏誤現象。以統計的角度來看,從一些特定的觀察結果要推論到一般性的結論時,樣本越多,後續推論愈正確,此即為統計上所謂的大數法則 (the law of large number)。當決策者採用代表性經驗法則做為樣本與母體的相似度判斷時,他們並不考慮樣本的大小,此發現與學者觀察到一般人在進行推理思考時,不太會從統計上的樣本大小來考慮之現象相呼應
  13. 要避免投資陷入代表性捷思法(Representativeness Heuristic),投資者應做到:
    1. 無論何時,都要關注基準概率 (base rate):很多人認為拋一枚均勻硬幣,如果首五次的結果都是正,那麼第六次很大機會是反。因為這個結果比較正常(令整體結果較接近1/2正反)。事實上,每次拋硬幣的結果都是獨立的,不論之前的結果如何,下次的結果都是半數機會正反。
    2. 切記概率不存在自我矯正行為:股票價格一直下跌並不意味著將來更可能上漲,一直上漲的股票也並不意味著將來更可能下跌。一些投資者老抱著一些深度套牢的股票不放,自認為已經兩年沒漲了,現在該輪到它了吧。投資者的這種股價會“自我矯正”的錯誤觀念,無疑是“把牢底坐穿”的一個很重要的原因。
    3. 不要被過度詳細的細節所迷惑:你對某公司掌握的訊息越是充分,越應該謹防決策失誤
    4. 不要誤解向平均數回歸的現象:股票價格的波動是正常現象,不應將此與一些偶然事件聯繫在一起
    5. 仔細檢驗,注意自己在推理過程中存在的謬誤:評估與預測時要注意base-rate information,時時做好自我監督與自我控制
  14. 賭徒謬誤(The Gambler's Fallacy)亦稱為蒙地卡羅謬誤(The Monte Carlo Fallacy),是一種機率謬誤,主張由於某事發生了很多次,因此接下來不太可能發生;或者由於某事很久沒發生,因此接下來很可能會發生。賭徒謬誤的思維方式像是如此:拋一枚公平的硬幣,連續出現越多次正面朝上,下次拋出正面的機率就越小,拋出反面的機率就越大。其實正反兩面發生機率永遠是 1/2,並不會因為前幾次都出現正面,接下來出現反面的機率就會超過 1/2,不要誤會機率會自我修正
  15. Insensitivity to predictability:人常會依照自己的喜好,去看自己想看的資訊,並根據這些片段的資訊做預測,在缺乏詳細資料的佐證下做出自滿的決定
  16. The illusion of validity(效度的錯覺):人們常會根據最具代表性的 input 來預測可能的 outcome,而其自信的來源則是來自其代表性的程度,卻忘了還有其他可能會影響 output 的因素或限制。在股票市場上也是。許多積極買賣股票的人,以為自己知道股票的真實價值,以為自己知道的比其他人多,也是身陷”效度的錯覺”。帶來這種錯覺最主要的原因在於,這些投資人使用一些看起來”非常高明”的方法在研判狀況。不論是技術分析,或是基本分析。這些方法甚至有一些漂亮得不得了的名字,譬如xxx選股神功。讓人以為自己學了之後,就會像張無忌學了九陽神功,一統江湖。
  17. Misconceptions of regression:是一種非形式謬誤,係因未考慮統計學上隨機起落的迴歸現象,造成不恰當的因果推論。例如小明發燒二天後吃退燒藥,燒就退了。因此,小明燒退是退燒藥的效果。但是發燒二天後,即使不吃藥也很可能自行好轉,不能就此認定是藥物的效果。又如學生在這次測驗中拿了100分滿分,老師和家長稱讚他後,他下次測驗只拿了95分。結果,他被罵了。然後,他在第三次拿到滿分。由此得出結論,誇獎令學生驕傲,成績下降,責罵則令學生成績進步。但是一個人不可能永遠滿分,可能第二次不稱讚他都會拿95分,第三次不責罵也會拿到滿分。這是學生實力的本身,不能斷定受責罵或稱讚所影響。
  18. Conjunction Fallacy (合取謬誤) 是指面對多重特徵時,我們往往會認為「符合特徵多」的機率會比「符合特徵少」的機率高。生活中這種例子倒比基本比率謬誤還要多,像下面這則例子:某天騎車,看到路邊有一對年輕情侶被警察攔下來開罰單。這對情侶為什麼被攔下來呢?(1)是因為他們超速嗎? (2) 是因為他們超速又沒戴安全帽嗎?事實上,在台灣,超速跟沒戴安全帽都會吃上罰單,我們會錯誤地認為同時沒戴安全帽和超速的機率會比較高。
  19. 在教導員工時,獎勵比懲罰有效,獎勵進步,不要懲罰錯誤
  20. 第一次表現差的,第二次就會好一點,第一次表現好的,第二次會差一點。前面幾次的優劣根本不足以去評斷優劣更枉談要處罰或是獎勵,人的表現本來就是有好有壞。那我們該獎勵什麼呢?要獎勵平均值的提升才是,或是在考試的表現高於全體的平均值時
  21. 我們的生命是一個不好的循環,因為我們會對取悅我們的人好,對我們不喜歡的人不好,可是從統計上來看,我們都會因為對人家好而受處罰,對人家不好而受獎勵。我們對喜歡的人有所期待,但當他的表現不如預期時,就好像是對自己有所懲罰而不開心。同樣地,對我們不好的人總覺得他一無是處,那是已經設定好的定位,當他表現出一點不一樣的時候,我們就覺得是種進步。
  22. 迴歸均值 (regression to the mean) 是統計學上的必然現象,但是卻違反了人們的期待,因為我們通常都會希望好還要更好(像是手氣正旺,一直賭下去,肯定會贏更多),但事實上,只要是「異常表現」都勢必會往平均值修正、靠攏。當表現愈極端,均值迴歸的幅度就愈大。2個小訣竅,甩開不切實際的期待:
    1. 不要過度追求「好還要更好」:在打考績或制定業績目標時,要將個人過往的表現也納入考量,給予每個工作者正確且合理的目標。
    2. 不要輕信單次特殊事件:單月業績突然大好、網站流量暴增,都可能跟運氣有關,除非該表現能穩定持續一季以上,才能視為是常態。
  23. 當老師說,經驗告訴她,批評比讚美更有效時,她不明白的是,這一切都由於迴歸均值 (regression to the mean) ,學生的表現本來就是好好壞壞、起起伏伏,但是要記得,當學生的表現優於整體平均時再給讚美
  24. 當我們在面試應徵者時,也許第二輪面試比第一輪相較之下,沒有令人那麼印象深刻,有可能是應徵者怕我們失望,但更可能是他的第一輪面試超乎尋常的好,應徵者怕其表現迴歸均值 (regression to the mean)
  25. 我們篩選的過程是好的,但是不完美,所以我們應該要預期會迴歸均值 (regression to the mean) ,我們不應該感到驚訝,最優秀的候選人往往不能滿足我們的期望



2018/06/30

[Travel] 2018/06 北投

新北投車站
DSC03470

新北投圖書館
DSC03491

DSC03475

地熱谷
DSC03516

DSC03519

DSC03524

2018/06/16

[Java 8] Examples for LocalDate


package test.albert.datetime;

import java.time.LocalDate;
import java.time.Month;
import java.time.format.DateTimeFormatter;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class TestDateTime {

    private static final DateTimeFormatter FROMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    public static void main(String[] args) {
        TestDateTime test = new TestDateTime();
        DateRange today = test.getToday();
        log.debug("Get today: {} ", today.toString());

        DateRange yesterday = test.getYesterday();
        log.debug("Get yesterday: {} ", yesterday.toString());

        DateRange lastWeek = test.getLastWeek();
        log.debug("Get last week: {} ", lastWeek.toString());

        DateRange withinOneMonth = test.getWithinOneMonth();
        log.debug("Get within one month: {} ", withinOneMonth.toString());

        DateRange lastMonth = test.getLastMonth();
        log.debug("Get last month: {} ", lastMonth.toString());

        DateRange thisYear = test.getThisYear();
        log.debug("Get this year: {} ", thisYear.toString());

        DateRange lastYear = test.getLastYear();
        log.debug("Get last year: {} ", lastYear.toString());
    }

    /**
     * 計算起訖日期: 今天
     * 
     * @return start/end date
     */
    public DateRange getToday() {
        LocalDate now = LocalDate.now();
        DateRange dateRange = new DateRange(formatDate(now), formatDate(now));
        return dateRange;
    }

    /**
     * 計算起訖日期: 今天減去一天
     * 
     * @return start/end date
     */
    public DateRange getYesterday() {
        LocalDate now = LocalDate.now();
        LocalDate yesterday = now.minusDays(1);

        DateRange dateRange = new DateRange(formatDate(yesterday), formatDate(yesterday));
        return dateRange;
    }

    /**
     * 計算起訖日期: 今天減去六天到今天
     * 
     * @return start/end date
     */
    public DateRange getLastWeek() {
        LocalDate now = LocalDate.now();
        LocalDate lastWeek = now.minusDays(6);

        DateRange dateRange = new DateRange(formatDate(lastWeek), formatDate(now));
        return dateRange;
    }

    /**
     * 計算起訖日期: 今天減去一個月到今天
     * 
     * @return start/end date
     */
    public DateRange getWithinOneMonth() {
        LocalDate now = LocalDate.now();
        LocalDate lastMonth = now.minusMonths(1);

        DateRange dateRange = new DateRange(formatDate(lastMonth), formatDate(now));
        return dateRange;
    }

    /**
     * 計算起訖日期: 上個月的第一天到上個月的最後一天
     * 
     * @return start/end date
     */
    public DateRange getLastMonth() {
        LocalDate now = LocalDate.now();
        LocalDate lastMonth = now.minusMonths(1);

        DateRange dateRange = new DateRange(formatDate(lastMonth.withDayOfMonth(1)),
                formatDate(lastMonth.withDayOfMonth(lastMonth.lengthOfMonth())));
        return dateRange;
    }

    /**
     * 計算起訖日期: 今年度的第一天到今天
     * 
     * @return start/end date
     */
    public DateRange getThisYear() {
        LocalDate now = LocalDate.now();
        LocalDate from = LocalDate.of(now.getYear(), Month.JANUARY, 1);

        DateRange dateRange = new DateRange(formatDate(from), formatDate(now));
        return dateRange;
    }

    /**
     * 計算起訖日期: 去年度的第一天到去年度的最後一天
     * 
     * @return start/end date
     */
    public DateRange getLastYear() {
        LocalDate now = LocalDate.now();

        LocalDate from = LocalDate.of(now.getYear() - 1, Month.JANUARY, 1);
        LocalDate to = LocalDate.of(now.getYear() - 1, Month.DECEMBER, 31);

        DateRange dateRange = new DateRange(formatDate(from), formatDate(to));
        return dateRange;
    }

    private String formatDate(LocalDate date) {
        return date.format(FROMATTER);
    }

    @Data
    @AllArgsConstructor
    private static class DateRange {
        private String from;
        private String to;
    }

}


Console
2018-05-09 11:27:31.661 - DEBUG- t.a.datetime.TestDateTime - Get today: TestDateTime.DateRange(from=2018-05-09, to=2018-05-09)  
2018-05-09 11:27:31.664 - DEBUG- t.a.datetime.TestDateTime - Get yesterday: TestDateTime.DateRange(from=2018-05-08, to=2018-05-08)  
2018-05-09 11:27:31.664 - DEBUG- t.a.datetime.TestDateTime - Get last week: TestDateTime.DateRange(from=2018-05-03, to=2018-05-09)  
2018-05-09 11:27:31.664 - DEBUG- t.a.datetime.TestDateTime - Get within one month: TestDateTime.DateRange(from=2018-04-09, to=2018-05-09)  
2018-05-09 11:27:31.665 - DEBUG- t.a.datetime.TestDateTime - Get last month: TestDateTime.DateRange(from=2018-04-01, to=2018-04-30)  
2018-05-09 11:27:31.665 - DEBUG- t.a.datetime.TestDateTime - Get this year: TestDateTime.DateRange(from=2018-01-01, to=2018-05-09)  
2018-05-09 11:27:31.665 - DEBUG- t.a.datetime.TestDateTime - Get last year: TestDateTime.DateRange(from=2017-01-01, to=2017-12-31)  


2018/06/15

[Neo4j] Cypher Example

在 graph database 中,擁有以下 User 與 Movie 的關係:





以下有數個查詢的例子:
// 找出 John Johnson 與其朋友共同看過的電影
match (u:User)-[:IS_FRIEND_OF]->()-[:HAS_SEEN]->(m:Movie)
where u.name="John Johnson" and not((u)-[:HAS_SEEN]->(m))
return m as movie;




// 找出 John Johnson 的朋友看過的,但是 John Johnson 沒看過的電影
match (u:User)-[:IS_FRIEND_OF]->()-[:HAS_SEEN]->(m:Movie)
where u.name="John Johnson" and (u)-[:HAS_SEEN]->(m)
return m as movie;





// 找出大家看過的電影,剔除重複的電影
match (u:User)-[:HAS_SEEN]->(m:Movie)
return distinct m as movie





// 找出 yearOfBirth 比 John Johnson 大的朋友
match (u1:User)-[:IS_FRIEND_OF]-(friend:User)
where u1.name="John Johnson" and  friend.yearOfBirth > u1.yearOfBirth
return friend




// 找出 John Johnson 的朋友中,使用 gmail mailbox 的人
match (u1:User)-[:IS_FRIEND_OF]-(friend:User)
where u1.name="John Johnson" and friend.email =~ ".*@gmail.com"
return friend




// 找出每個人有幾個朋友 (數量以降冪排序)
match (u:User)-[:IS_FRIEND_OF]-()
return u as user, count(*) 
order by count(*) desc




// 找出 John Johnson 與其他節點的關係,並統計數量
match (u:User)-[rel]-()
where u.name="John Johnson"
with u.name as name, type(rel) as rel, count(*) as count
return name, rel, count



2018/06/14

[Neo4j] Importing data using spreadsheets

假設我想要在 neo4j 建立起下圖的關係


分析與執行步驟如下:



由關係圖可以看出會有七個節點,包含
  • 哆啦A夢
  • 大雄
  • 靜香
  • 小夫
  • 胖虎
  • 小叮鈴
  • 玉子 (大雄的媽媽)
  • 伸助 (大雄的爸爸)

這七個人,就分別是 graph database 中的七個節點,分別給予 id 與 label ,Excel 內容如下:


這七個人 (nodes) 之間的有九個關係:
  • 大雄的寵物是哆啦A夢
  • 大雄的配偶是靜香
  • 大雄的朋友是小夫
  • 大雄的朋友是胖虎
  • 小夫的朋友是胖虎
  • 哆啦A夢的妹妹是小叮鈴
  • 大雄的爸爸是伸助
  • 大雄的媽媽是玉子
  • 伸助的配偶是玉子

在 Excel 中,關係表示如下:


透過 Excel 內建的 CONCATENATE 語法,產生 create nodes / relationship 的 Cypher 語法
建立 nodes 的 Excel formula:
=CONCATENATE("create(n",A2, ":", ,C2, " {id:", A2, ", name:'",B2, "'}", ")")

建立 relationships 的 Excel formula:
=CONCATENATE("create(n",E2,")-[:",G2,"]->(n",H2,")")
依據上述 nodes 與 relationship ,產生的 Cypher 語法如下:

create(n1:男生 {id:1, name:'哆啦A夢'})
create(n2:男生 {id:2, name:'大雄'})
create(n3:女生 {id:3, name:'靜香'})
create(n4:男生 {id:4, name:'小夫'})
create(n5:男生 {id:5, name:'胖虎'})
create(n6:女生 {id:6, name:'小叮鈴'})
create(n7:女生 {id:7, name:'玉子'})
create(n8:男生 {id:8, name:'伸助'})

create(n2)-[:PET_OF]->(n1)
create(n2)-[:SPOUSE_OF]->(n3)
create(n2)-[:FRIEND_OF]->(n4)
create(n2)-[:FRIEND_OF]->(n5)
create(n4)-[:FRIEND_OF]->(n5)
create(n1)-[:SISTER_OF]->(n6)
create(n2)-[:MOTHER_OF]->(n7)
create(n2)-[:FATHER_OF]->(n8)
create(n8)-[:SPOUSE_OF]->(n7)

將上述語法貼到 Neo4j Browser 並執行


產生的 graph 如下:



2018/06/13

[PostgreSQL] How to update data from a sub-query

Problem
I have two tables, project and intent, in my database.


I import data into intent table, but found out I mistype some data in intent.value column. All data in intent.value should start with qa_.

How to iron out this problem using update statement?

How-To
Here has an example to fix this problem:
1
2
3
4
5
6
7
8
9
  update intent
  set value = source.new_value
  from(
      select id as intent_id, value, 'qa_' || value as new_value, project_id as proj_id
      from intent 
      where project_id= (select id from project where identifier='test')
      and substring(value, 1, 3) <> 'qa_' 
  ) as source
  where id = source.intent_id and project_id = source.proj_id