āĻ ā§āϝāĻžāĻĄāĻŽāĻŋāύ āĻĢāĻŋāϞā§āĻāĻžāϰā§āϰ āĻāύā§āϝ PostgreSQL generated columns āĻĻāĻŋā§ā§ āĻĻā§āϰā§āϤāϤāĻž
PostgreSQL generated columns āĻā§āĻāĻžāĻŦā§ āĻ ā§āϝāĻžāĻĄāĻŽāĻŋāύ āϏā§āĻā§āϰāĻŋāύā§āϰ āĻĢāĻŋāϞā§āĻāĻžāϰ āĻ āϏā§āϰā§āĻāĻŋāĻ āĻĻā§āϰā§āϤ āĻāϰāϤ⧠āĻĒāĻžāϰā§, āĻāĻĻāĻžāĻšāϰāĻŖ āĻ āĻĻā§āϰā§āϤ āĻā§āĻāĻŋāĻ āϏāĻš āĻĒāĻĄāĻŧā§āύāĨ¤

āĻā§āύ āĻ
ā§āϝāĻžāĻĄāĻŽāĻŋāύ āϏā§āĻā§āϰāĻŋāύ āĻĻā§āϰā§āϤ āϧā§āϰ āĻāĻŦāĻ āĻāĻāĻŋāϞ āĻšā§ā§ āĻāĻ ā§\n\nāĻ
ā§āϝāĻžāĻĄāĻŽāĻŋāύ āϏā§āĻā§āϰāĻŋāύāĻā§āϞ⧠āϏāĻžāϧāĻžāϰāĻŖāϤ āϏāϰāϞāĻāĻžāĻŦā§ āĻļā§āϰ⧠āĻšā§: āĻāĻāĻāĻŋ āĻā§āĻŦāĻŋāϞ, āĻā§ā§āĻāĻāĻž āĻĢāĻŋāϞā§āĻāĻžāϰ, āĻšā§āϤ⧠âāύāϤā§āύāĻā§āϞ⧠āĻĒā§āϰāĻĨāĻŽâ āύāĻžāĻŽā§ āĻāĻāĻāĻŋ āϏā§āϰā§āĻāĨ¤ āϤāĻžāϰāĻĒāϰ āĻāĻžāĻ āĻŦāĻžā§āϤ⧠āĻļā§āϰ⧠āĻāϰā§āĨ¤ āϏāĻžāĻĒā§āϰā§āĻ āĻāĻžāĻāĻŦā§ āύāĻžāĻŽ, āĻāĻŽā§āĻāϞ, āĻĢā§āύ āĻĻāĻŋā§ā§ āĻā§āĻāĻ āĻāϰāϤā§āĨ¤ āϏā§āϞāϏ āĻāĻžāĻāĻŦā§ âāĻļā§āώ āĻāĻžāϰā§āϝāĻāϞāĻžāĻĒâ āĻ
āύā§āϝāĻžā§ā§ āϏāĻžāĻāĻžāϤā§āĨ¤ āĻĢāĻžāĻāύā§āϝāĻžāύā§āϏ āĻāĻžāĻāĻŦā§ âāĻŦāĻā§ā§āĻž āĻŦā§āϝāĻžāϞāĻžāύā§āϏâ āĻ
āύā§āϝāĻžā§ā§ āĻĢāĻŋāϞā§āĻāĻžāϰāĨ¤ āĻĒā§āϰāϤāĻŋ āĻ
āύā§āϰā§āϧ⧠āĻļāϰā§āϤ, āĻā§ā§āύ, āĻāĻŦāĻ āĻ
āϤāĻŋāϰāĻŋāĻā§āϤ āĻāĻŖāύāĻž āĻŦāĻžā§ā§āĨ¤\n\nāĻ
āϧāĻŋāĻāĻžāĻāĻļ āĻ
ā§āϝāĻžāĻĄāĻŽāĻŋāύ āϤāĻžāϞāĻŋāĻāĻž āĻāĻāĻ āĻāĻžāϰāĻŖā§ āϧā§āϰ āĻšā§: āĻĒā§āϰāϤāĻŋāĻāĻŋ āĻā§āϞāĻŋāĻ āĻā§ā§ā§āϰāĻŋ āĻŦāĻĻāϞ⧠āĻĻā§ā§āĨ¤ āĻĢāĻŋāϞā§āĻāĻžāϰ āĻ āϏā§āϰā§āĻ āĻāϰāĻžāϰ āϏāĻŽā§ āĻĄāĻžāĻāĻžāĻŦā§āϏ āĻ
āύā§āĻ āϰ⧠āϏā§āĻā§āϝāĻžāύ āĻāϰāϤ⧠āĻĒāĻžāϰā§, āĻŦāĻŋāĻļā§āώāϤ āϝāĻāύ āĻā§ā§ā§āϰāĻŋ āĻĒā§āϰāϤāĻŋāĻāĻŋ āϰā§āϤ⧠āĻāĻāĻāĻŋ āĻŽāĻžāύ āĻšāĻŋāϏāĻžāĻŦ āĻāϰ⧠āϤāĻžāϰāĻĒāϰ āϏāĻŋāĻĻā§āϧāĻžāύā§āϤ āύā§ā§ āĻā§āύāĻāĻŋ āĻŽā§āϝāĻžāĻ āĻāϰā§āĨ¤\n\nāĻāĻāĻāĻŋ āϏāĻžāϧāĻžāϰāĻŖ āĻŽā§ā§ āĻāϏ⧠āϝāĻāύ WHERE āĻāĻŦāĻ ORDER BY āĻāĻā§āϏāĻĒā§āϰā§āĻļāύ āĻĻāĻŋā§ā§ āĻāϰ⧠āĻāĻ ā§āĨ¤ āϏāĻžāϧāĻžāϰāĻŖ āĻāϞāĻžāĻŽā§āϰ āĻŦāĻĻāϞ⧠āĻāĻĒāύāĻŋ lower(email), date_trunc('day', last_seen_at), āĻŦāĻž āĻāĻāĻžāϧāĻŋāĻ āϏā§āĻā§āϝāĻžāĻāĻžāϏāĻā§ āĻāĻ âāĻŦāĻžāĻā§āĻâ āĻ āĻŽāĻžāύāĻāĻŋāϤā§āϰ āĻāϰāϤ⧠CASE āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠āĻĢāĻŋāϞā§āĻāĻžāϰ āĻāϰā§āύāĨ¤ āĻāĻ āĻāĻā§āϏāĻĒā§āϰā§āĻļāύāĻā§āϞ⧠āĻļā§āϧā§āĻ āϧā§āϰ āύ⧠â āĻāĻā§āϞ⧠SQL āĻĒā§āϤ⧠āĻāĻ āĻŋāύ āĻāϰā§, āĻāύāĻĄā§āĻā§āϏ āĻāϰāĻž āĻāĻ āĻŋāύ āĻāϰā§, āĻāĻŦāĻ āϏāĻšāĻā§ āĻā§āϞ āĻšāĻā§āĻžāϰ āϏā§āϝā§āĻ āϤā§āϰāĻŋ āĻāϰā§āĨ¤\n\nāĻ
āĻā§āĻāĻžāϞ⧠āĻ
ā§āϝāĻžāĻĄāĻŽāĻŋāύ SQL āϏāĻžāϧāĻžāϰāĻŖāϤ āĻā§ā§āĻāĻāĻŋ āĻĒā§āύāϰāĻžāĻŦā§āϤā§āϤ āĻĒā§āϝāĻžāĻāĻžāϰā§āύ āĻĨā§āĻā§āĻ āĻāύā§āĻŽāĻžā§:\n\n- āĻāĻāĻāĻŋ âāϏāĻžāϰā§āĻâ āĻāύāĻĒā§āĻ āϝāĻž āĻŦāĻŋāĻāĻŋāύā§āύ āύāĻŋā§āĻŽā§ āĻāĻāĻžāϧāĻŋāĻ āĻĢāĻŋāϞā§āĻĄ āĻā§āĻ āĻāϰā§\n- āĻā§āĻĒāύā§āύ āĻŽāĻžāύ āĻĻāĻŋā§ā§ āϏā§āϰā§āĻ āĻāϰāĻž (āĻĢā§āϞ āύā§āĻŽ, āĻĒā§āϰāĻžāϧāĻžāύā§āϝ āϏā§āĻā§āϰ, âāĻļā§āώ āĻ
āϰā§āĻĨāĻĒā§āϰā§āύ āĻāĻā§āύā§āĻâ)\n- āĻŦā§āϝāĻŦāϏāĻžāϝāĻŧāĻŋāĻ āύāĻŋā§āĻŽāĻā§āϞ⧠āϏā§āĻā§āϰāĻŋāύ āĻā§ā§ā§ āĻāĻĒāĻŋ āĻāϰāĻž (active vs inactive, paid vs overdue)\n- āĻā§āĻ âāĻšā§āϞā§āĻĒāĻžāϰâ āĻā§āĻāĻ (trim, lower, coalesce) āĻā§āĻŋā§ā§ āĻĨāĻžāĻāĻž\n- āĻāĻāĻ āĻāĻŖāĻŋāϤ āĻāϰāĻž āĻŽāĻžāύ āϤāĻžāϞāĻŋāĻāĻž, āĻĢāĻŋāϞā§āĻāĻžāϰ, āĻāĻŦāĻ āϏā§āϰā§āĻāĻŋāĻ āĻ āĻŦāĻžāϰāĻŦāĻžāϰ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻšā§\n\nāĻāĻŋāĻŽāĻā§āϞ⧠āĻĒā§āϰāĻžāϝāĻŧāĻ āĻāĻāĻŋ āĻ
ā§āϝāĻžāĻĒ āϞā§ā§āĻžāϰ⧠āϞā§āĻāĻžāϤ⧠āĻāĻžā§: āĻĄāĻžā§āύāĻžāĻŽāĻŋāĻ āĻā§ā§ā§āϰāĻŋ āĻŦāĻŋāϞā§āĻĄāĻžāϰ, āĻļāϰā§āϤāĻāĻŋāϤā§āϤāĻŋāĻ āĻā§ā§āύ, āĻŦāĻž āĻā§āĻĄā§ āĻĒā§āϰāĻŋāĻāĻŽā§āĻĒāĻŋāĻāĻā§āĻĄ āĻŽāĻžāύāĨ¤ āϤāĻž āĻāĻžāĻ āĻāϰāϞā§āĻ, āĻāĻāĻŋ UI āĻāĻŦāĻ āĻĄāĻžāĻāĻžāĻŦā§āϏā§āϰ āĻŽāϧā§āϝ⧠āϞāĻāĻŋāĻ āĻāĻžāĻ āĻāϰ⧠āĻĻā§ā§, āĻĢāϞ⧠āϧā§āϰ āĻā§ā§ā§āϰāĻŋ āĻĄāĻŋāĻŦāĻžāĻ āĻāϰāĻž āĻāώā§āĻāϏāĻžāϧā§āϝ āĻšā§ā§ āĻĒā§ā§āĨ¤\n\nāϞāĻā§āώā§āϝ āϏā§āĻāĻž: āĻĻā§āϰā§āϤ āĻā§ā§ā§āϰāĻŋ āϝā§āĻā§āϞ⧠āĻĒā§āϤ⧠āϏāĻšāĻ āĻĨāĻžāĻā§āĨ¤ āϝāĻāύ āĻā§āύ⧠āĻšāĻŋāϏāĻžāĻŦ āĻāϰāĻž āĻŽāĻžāύ āĻŦāĻžāϰāĻŦāĻžāϰ āĻ
ā§āϝāĻžāĻĄāĻŽāĻŋāύ āϏā§āĻā§āϰāĻŋāύ⧠āĻĻā§āĻāĻž āϝāĻžā§, PostgreSQL generated columns āϏā§āĻ āύāĻŋā§āĻŽāĻā§ āĻāĻ āĻāĻžā§āĻāĻžā§ āϰā§āĻā§ āĻĄāĻžāĻāĻžāĻŦā§āϏāĻā§ āĻ
āĻĒā§āĻāĻŋāĻŽāĻžāĻāĻ āĻāϰāĻžāϰ āϏā§āϝā§āĻ āĻĻā§ā§āĨ¤\n\n## āĻā§āύāĻžāϰā§āĻā§āĻĄ āĻāϞāĻžāĻŽ āϏāϰāϞ āĻāĻžāώāĻžā§\n\nāĻāĻāĻāĻŋ generated column āĻšāĻā§āĻā§ āĻā§āĻŦāĻŋāϞā§āϰ āĻāĻ āϏāĻžāϧāĻžāϰāĻŖ āĻāϞāĻžāĻŽ āϝāĻžāϰ āĻŽāĻžāύ āĻ
āύā§āϝ āĻāϞāĻžāĻŽāĻā§āϞ⧠āĻĨā§āĻā§ āĻšāĻŋāϏāĻžāĻŦ āĻāϰāĻž āĻšā§āĨ¤ āĻāĻĒāύāĻŋ āĻŽāĻžāύāĻāĻŋ āύāĻŋāĻā§ āϞāĻŋāĻā§āύ āύāĻžāĨ¤ PostgreSQL āĻāĻĒāύāĻžāϰ āĻĻā§āĻā§āĻž āĻāĻā§āϏāĻĒā§āϰā§āĻļāύ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠āĻāĻāĻŋ āĻĒā§āϰāĻŖ āĻāϰā§āĨ¤\n\nPostgreSQL-āĻ generated columns āϏā§āĻā§āϰ āĻšā§āĨ¤ PostgreSQL āĻāĻāĻāĻŋ āϰ⧠āĻāύāϏāĻžāϰā§āĻ āĻ
āĻĨāĻŦāĻž āĻāĻĒāĻĄā§āĻ āĻšāϞ⧠āĻŽāĻžāύāĻāĻŋ āĻāĻŖāύāĻž āĻāϰā§, āϤāĻžāϰāĻĒāϰ āĻĄāĻŋāϏā§āĻā§ āĻ
āύā§āϝ āĻāϞāĻžāĻŽā§āϰ āĻŽāϤā§āĻ āϏāĻāϰāĻā§āώāĻŖ āĻāϰā§āĨ¤ āĻ
ā§āϝāĻžāĻĄāĻŽāĻŋāύ āϏā§āĻā§āϰāĻŋāύā§āϰ āĻāύā§āϝ āĻāĻāĻŋāĻ āϏāĻžāϧāĻžāϰāĻŖāϤ āĻāĻžāύ: āĻĻā§āϰā§āϤ āϰāĻŋāĻĄ āĻāĻŦāĻ āĻāĻŖāĻŋāϤ āĻāϰāĻž āĻŽāĻžāύ āĻāύāĻĄā§āĻā§āϏ āĻāϰāĻžāϰ āĻā§āώāĻŽāϤāĻžāĨ¤\n\nāĻāĻāĻŋ āĻĒā§āϰāϤāĻŋāĻāĻŋ āĻā§ā§ā§āϰāĻŋāϰ āĻā§āϤāϰ⧠āĻāĻāĻ āĻāĻŖāύāĻž āĻŦāĻžāϰ āĻŦāĻžāϰ āĻāϰāĻžāϰ āĻĨā§āĻā§ āĻāϞāĻžāĻĻāĻžāĨ¤ āϝāĻĻāĻŋ āĻāĻĒāύāĻŋ āĻŦāĻžāϰāĻŦāĻžāϰ āϞāĻŋāĻā§āύ WHERE lower(email) = lower($1) āĻŦāĻž ORDER BY last_name || ', ' || first_name â āĻāĻĒāύāĻŋ āĻŦāĻžāϰāĻŦāĻžāϰ āĻāϰāĻ āĻĻā§āĻŦā§āύ āĻāĻŦāĻ SQL āĻā§āϞāĻŽā§āϞ⧠āĻšāĻŦā§āĨ¤ āĻāĻāĻāĻŋ generated column āϏā§āĻ āĻĒā§āύāϰāĻžāĻŦā§āϤā§āϤ āĻāĻŖāύāĻžāĻā§ āĻā§āĻŦāĻŋāϞ āϏāĻāĻā§āĻāĻžā§ āϏāϰāĻŋā§ā§ āĻĻā§ā§āĨ¤ āĻāĻĒāύāĻžāϰ āĻā§ā§ā§āϰāĻŋ āϏāϰāϞ āĻšā§, āĻāĻŦāĻ āĻĢāϞāĻžāĻĢāϞ āϏāĻŦ āĻāĻžā§āĻāĻžā§ āϏāĻā§āĻāϤāĻŋāĻĒā§āϰā§āĻŖ āĻĨāĻžāĻā§āĨ¤\n\nāϝāĻāύ āϏā§āϰā§āϏ āĻĄā§āĻāĻž āĻŦāĻĻāϞ⧠āϝāĻžā§, PostgreSQL āϏā§āĻŦā§āĻāĻā§āϰāĻŋā§āĻāĻžāĻŦā§ āĻ āϰā§-āĻāϰ āĻāύā§āϝ generated āĻŽāĻžāύ āĻāĻĒāĻĄā§āĻ āĻāϰā§āĨ¤ āĻāĻĒāύāĻžāϰ āĻ
ā§āϝāĻžāĻĒāĻā§ āϤāĻž āϏā§āĻŽāϰāĻŖ āϰāĻžāĻāĻžāϰ āĻĻāϰāĻāĻžāϰ āύā§āĻāĨ¤\n\nāĻāĻāĻāĻŋ āϏāĻšāĻ āĻŽā§āύā§āĻāĻžāϞ āĻŽāĻĄā§āϞ:\n\n- āϏā§āϤā§āϰ āĻāĻāĻŦāĻžāϰ āϏāĻāĻā§āĻāĻžā§āĻŋāϤ āĻāϰā§āύāĨ¤\n- PostgreSQL āϞāĻŋāĻāĻžāϰ āϏāĻŽā§ āĻāĻāĻŋ āĻāĻŖāύāĻž āĻāϰā§āĨ¤\n- āĻā§ā§ā§āϰāĻŋ āĻāĻāĻŋ āϏāĻžāϧāĻžāϰāĻŖ āĻāϞāĻžāĻŽā§āϰ āĻŽāϤ⧠āĻĒā§ā§āĨ¤\n- āϝā§āĻšā§āϤ⧠āĻāĻāĻŋ āϏā§āĻā§āϰ āĻāϰāĻž āĻšā§, āĻāĻĒāύāĻŋ āĻāĻāĻŋ āĻāύāĻĄā§āĻā§āϏāĻ āĻāϰāϤ⧠āĻĒāĻžāϰā§āύāĨ¤\n\nāĻĒāϰāĻŦāϰā§āϤ⧠āϏāĻŽā§ā§ āϏā§āϤā§āϰ āĻŦāĻĻāϞāĻžāϞā§, āĻāĻĒāύāĻžāϰ āĻāĻāĻāĻŋ āϏā§āĻāĻŋāĻŽāĻž āĻĒāϰāĻŋāĻŦāϰā§āϤāύ āϞāĻžāĻāĻŦā§āĨ¤ āĻāĻāĻŋ āϝā§āĻā§āύ āĻŽāĻžāĻāĻā§āϰā§āĻļāύā§āϰ āĻŽāϤ⧠āĻĒāϰāĻŋāĻāϞā§āĻĒāύāĻž āĻāϰā§āύ, āĻāĻžāϰāĻŖ āĻŦāĻŋāĻĻā§āϝāĻŽāĻžāύ āϰ⧠āĻā§āϞā§āĻ āύāϤā§āύ āĻāĻā§āϏāĻĒā§āϰā§āĻļāύā§āϰ āϏāĻā§āĻā§ āĻāĻĒāĻĄā§āĻ āĻšāĻŦā§āĨ¤\n\n## āĻĢāĻŋāϞā§āĻāĻžāϰ āĻ āϏā§āϰā§āĻāĻŋāĻā§ā§ āĻšāĻŋāϏāĻžāĻŦ āĻāϰāĻž āĻĢāĻŋāϞā§āĻĄā§āϰ āĻāĻžāϞ⧠āĻŦā§āϝāĻŦāĻšāĻžāϰ\n\nGenerated columns āϏā§āĻ āϏāĻŦ āĻā§āώā§āϤā§āϰ⧠āĻāĻā§āĻā§āĻŦāϞ āϝāĻāύ āĻŽāĻžāύāĻāĻŋ āϏāĻŦāϏāĻŽā§ āĻ
āύā§āϝ āĻāϞāĻžāĻŽ āĻĨā§āĻā§ āύāĻŋāϰā§āĻāϰ āĻāϰ⧠āĻāĻŦāĻ āĻāĻĒāύāĻŋ āϏā§āĻāĻŋāϤ⧠āĻĒā§āϰāĻžāϝāĻŧāĻ āĻĢāĻŋāϞā§āĻāĻžāϰ āĻŦāĻž āϏā§āϰā§āĻ āĻāϰā§āύāĨ¤ āĻāĻ-āĻŦāĻžāϰā§āϰ āϰāĻŋāĻĒā§āϰā§āĻā§āϰ āĻāύā§āϝ āĻāĻā§āϞ⧠āϤāϤāĻāĻž āĻāĻĒāĻāĻžāϰ⧠āύā§āĨ¤\n\n### āĻŦā§āϝāĻŦāĻšāĻžāϰāĻāĻžāϰā§āϰāĻž āĻŦāĻžāϏā§āϤāĻŦā§ āϝ⧠āϏāĻžāϰā§āĻ āĻĢāĻŋāϞā§āĻĄ āĻāĻžāύ\n\nāĻ
ā§āϝāĻžāĻĄāĻŽāĻŋāύ āϏāĻžāϰā§āĻ āĻā§āĻŦ āĻāĻŽāĻ âāĻļā§āĻĻā§āϧâ āϏāĻžāϰā§āĻ āĻšā§āĨ¤ āĻŽāĻžāύā§āώ āĻāĻļāĻž āĻāϰ⧠āϏāĻžāϰā§āĻ āĻŦāĻā§āϏ āĻāĻžāĻŽā§āϞāĻžā§, āĻ
āĻĒā§āϰāϤāĻŋāώā§āĻ āĻŋāϤ āĻā§āϏāĻŋāĻ āĻāĻŦāĻ āĻ
āϤāĻŋāϰāĻŋāĻā§āϤ āϏā§āĻĒā§āϏ āϏāĻžāĻŽāϞāĻžāĻŦā§āĨ¤ āϝāĻĻāĻŋ āĻāĻĒāύāĻŋ āĻāĻāĻāĻŋ generated âsearch keyâ āϏāĻāϰāĻā§āώāĻŖ āĻāϰā§āύ āϝāĻž āĻāĻā§ āĻĨā§āĻā§āĻ āύāϰāĻŽāĻžāϞāĻžāĻāĻ āĻāϰāĻž, āĻāĻĒāύāĻžāϰ WHERE āĻā§āϞāĻ āĻĒā§āϤ⧠āϏāĻšāĻ āĻĨāĻžāĻāĻŦā§ āĻāĻŦāĻ āϏā§āĻā§āϰāĻŋāύ āĻā§ā§ā§ āĻāĻāϰāĻŖ āĻāĻāĻ āĻĨāĻžāĻāĻŦā§āĨ¤\n\nāĻāĻžāϞ⧠āĻĒā§āϰāĻžāϰā§āĻĨā§ āĻšāϤ⧠āĻĒāĻžāϰā§: āĻāĻāϤā§āϰāĻŋāϤ āĻĢā§āϞ āύāĻžāĻŽ, āĻā§āĻ āĻšāĻžāϤā§āϰ āĻŦāĻžāύāĻžāύ⧠āĻā§āϰāĻŋāĻŽ āĻāϰāĻž āĻā§āĻā§āϏāĻ, āĻ
āϤāĻŋāϰāĻŋāĻā§āϤ āϏā§āĻĒā§āϏ āĻā§āĻā§ āĻĻā§ā§āĻž, āĻ
āĻĨāĻŦāĻž āĻāĻāĻžāϧāĻŋāĻ āĻĢāĻŋāϞā§āĻĄ āĻĨā§āĻā§ āĻĒāĻžāĻā§āĻž āϏā§āĻā§āϝāĻžāĻāĻžāϏ āϞā§āĻŦā§āϞāĨ¤\n\nāĻāĻĻāĻžāĻšāϰāĻŖ: āĻĒā§āϰāϤāĻŋāĻāĻŋ āĻā§ā§ā§āϰāĻŋāϤ⧠lower(trim(first_name || ' ' || last_name)) āĻŦāĻžāϰāĻŦāĻžāϰ āϞā§āĻāĻžāϰ āĻŦāĻĻāϞ⧠full_name_key āĻāĻāĻŦāĻžāϰ āĻā§āύāĻžāϰā§āĻ āĻāϰ⧠āϤāĻžāϰ āĻāĻĒāϰ āĻĢāĻŋāϞā§āĻāĻžāϰ āĻāϰā§āύāĨ¤\n\n### āĻŽāĻžāύā§āώ āĻāĻŋāĻāĻžāĻŦā§ āϏā§āϰā§āĻ āĻāϰ⧠āϤāĻžāϰ āϏāĻžāĻĨā§ āĻŽāĻŋāϞāĻŋā§ā§ āϏā§āϰā§āĻ āĻā§\n\nāϏā§āϰā§āĻāĻŋāĻ āĻšāĻā§āĻā§ āϝā§āĻāĻžāύ⧠āĻāĻŖāĻŋāϤ āĻāϰāĻž āĻĢāĻŋāϞā§āĻĄ āĻĻā§āϰā§āϤāĻ āϏā§āĻŦāĻŋāϧāĻž āĻĻā§ā§, āĻāĻžāϰāĻŖ āϏā§āϰā§āĻāĻŋāĻ PostgreSQL-āĻā§ āĻ
āύā§āĻ āϰā§-āϤ⧠āĻāĻā§āϏāĻĒā§āϰā§āĻļāύ āĻŽā§āϞā§āϝāĻžā§āύ āĻāϰāĻžāϤ⧠āĻŦāĻžāϧā§āϝ āĻāϰā§āĨ¤\n\nāϏāĻžāϧāĻžāϰāĻŖ āϏā§āϰā§āĻ āĻā§-āϤ⧠āĻĨāĻžāĻā§ āĻāĻāĻāĻŋ āύāĻŽā§āĻŦāϰ āϰâā§āϝāĻžāĻāĻ (āĻĒā§āϞā§āϝāĻžāύ āĻāĻŋā§āĻžāϰāĻā§ 1,2,3 āĻŽā§āϝāĻžāĻĒ āĻāϰāĻž), āĻāĻāĻāĻŋ âāϏāϰā§āĻŦāĻļā§āώ āĻāĻžāϰā§āϝāĻāϞāĻžāĻĒâ āĻāĻžāĻāĻŽāϏā§āĻā§āϝāĻžāĻŽā§āĻĒ (āϝā§āĻŽāύ āĻĻā§āĻ āĻāĻžāĻāĻŽāϏā§āĻā§āϝāĻžāĻŽā§āĻĒā§āϰ max), āĻŦāĻž āĻā§āĻā§āϏāĻ āĻšāĻŋāϏā§āĻŦā§ āϏāĻ āĻŋāĻāĻāĻžāĻŦā§ āϏāĻžāĻāĻžāύ⧠āĻĒā§āϝāĻžāĻĄ āĻāϰāĻž āĻā§āĻĄāĨ¤\n\nāϝāĻāύ āϏā§āϰā§āĻ āĻā§āĻāĻŋ āĻāĻāĻāĻŋ āϏāĻžāϧāĻžāϰāĻŖ āĻāύāĻĄā§āĻā§āϏ āĻāϰāĻž āĻāϞāĻžāĻŽ āĻšā§, ORDER BY āĻ
āύā§āĻ āϏāϏā§āϤāĻž āĻšā§ā§ āϝāĻžā§āĨ¤\n\n### āĻĻā§āϰā§āϤ āĻĢāĻŋāϞā§āĻāĻžāϰā§āϰ āĻāύā§āϝ āĻĄā§āϰāĻžāĻāĻā§āĻĄ āĻĢā§āϞā§āϝāĻžāĻ\n\nāĻ
ā§āϝāĻžāĻĄāĻŽāĻŋāύ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻāĻžāϰā§āϰāĻž âOverdueâ āĻŦāĻž âHigh valueâ āϧāϰāĻžāϰ āĻā§āĻāĻŦāĻā§āϏ āĻā§āĻŦ āĻĒāĻāύā§āĻĻ āĻāϰā§āĨ¤ āϝāĻĻāĻŋ āϞāĻāĻŋāĻāĻāĻŋ āϏā§āĻĨāĻŋāϤāĻŋāĻļā§āϞ āĻāĻŦāĻ āĻā§āĻŦāϞ āϰā§-āĻĄā§āĻāĻžāϰ āĻāĻĒāϰ āύāĻŋāϰā§āĻāϰ āĻāϰ⧠āϤāĻžāĻšāϞ⧠āĻāĻā§āϞ⧠generated column āĻšāĻŋāϏā§āĻŦā§ āĻāĻžāϞ āĻāĻžāĻ āĻāϰā§āĨ¤\n\nāĻāĻĻāĻžāĻšāϰāĻŖāϏā§āĻŦāϰā§āĻĒ, āϝāĻĻāĻŋ āĻāĻžāϏā§āĻāĻŽāĻžāϰ āϤāĻžāϞāĻŋāĻāĻžā§ âHas unread messagesâ āĻāĻŦāĻ âIs overdueâ āϞāĻžāĻā§, āϤāĻžāĻšāϞ⧠āĻāĻāĻāĻŋ generated has_unread boolean (āϝāĻž unread_count > 0 āĻĨā§āĻā§ āĻāϏā§) āĻāĻŦāĻ is_overdue (āϝāĻž due_date < now() āĻāĻŦāĻ paid_at is null āĻĨā§āĻā§ āύāĻŋāϰā§āϧāĻžāϰāĻŋāϤ) UI āĻĢāĻŋāϞā§āĻāĻžāϰāĻā§ āϏāϰāϞ āĻļāϰā§āϤ⧠āĻŦāĻĻāϞ⧠āĻĻā§ā§āĨ¤\n\n## generated columns, āĻāύāĻĄā§āĻā§āϏ āĻ āĻ
āύā§āϝāĻžāύā§āϝ āĻŦāĻŋāĻāϞā§āĻĒā§āϰ āĻŽāϧā§āϝ⧠āύāĻŋāϰā§āĻŦāĻžāĻāύ\n\nāĻ
ā§āϝāĻžāĻĄāĻŽāĻŋāύ āϏā§āĻā§āϰāĻŋāύāĻā§āϞā§āĻā§ āϤāĻŋāύāĻāĻŋ āĻāĻŋāύāĻŋāϏ āϞāĻžāĻā§: āĻĻā§āϰā§āϤ āĻĢāĻŋāϞā§āĻāĻžāϰāĻŋāĻ, āĻĻā§āϰā§āϤ āϏā§āϰā§āĻāĻŋāĻ, āĻāĻŦāĻ āĻāĻŽāύ SQL āϝāĻž āĻŽāĻžāϏ āĻĒāϰ⧠āĻĒā§āϤ⧠āϏāĻšāĻ āĻĨāĻžāĻā§āĨ¤ āĻŦāĻžāϏā§āϤāĻŦ āϏāĻŋāĻĻā§āϧāĻžāύā§āϤ āĻšāĻā§āĻā§ āĻšāĻŋāϏāĻžāĻŦāĻāĻŋ āĻā§āĻĨāĻžā§ āϰāĻžāĻāĻž āĻāĻāĻŋāϤ: āĻā§āĻŦāĻŋāϞā§, āĻāύāĻĄā§āĻā§āϏā§, āĻāĻŋāĻāϤā§, āύāĻž āĻāĻŋ āĻ
ā§āϝāĻžāĻĒ āĻā§āĻĄā§āĨ¤\n\nGenerated columns āĻāĻĒāϝā§āĻā§ āϝāĻāύ āĻāĻĒāύāĻŋ āĻāĻžāύ āϝ⧠āĻŽāĻžāύāĻāĻŋ āĻāĻāĻāĻŋ āĻŦāĻžāϏā§āϤāĻŦ āĻāϞāĻžāĻŽā§āϰ āĻŽāϤ⧠āĻāĻāϰāĻŖ āĻāϰā§āĻ: āϰā§āĻĢāĻžāϰ āĻāϰāĻž āϏāĻšāĻ, SELECT-āĻ āĻĻā§āĻāĻž āϝāĻžā§, āĻāĻŦāĻ āύāϤā§āύ āĻĢāĻŋāϞā§āĻāĻžāϰ āϝā§āĻ āĻāϰāĻžāϰ āϏāĻŽā§ āĻā§āϞ⧠āύāĻž āϝāĻžāĻā§āĻž āϝāĻžā§āĨ¤ āĻāĻā§āϞ⧠āϏāĻžāϧāĻžāϰāĻŖ āĻāύāĻĄā§āĻā§āϏā§āϰ āϏāĻā§āĻā§ āĻāĻžāϞ⧠āĻŦā§āĻāĻžāĻĒā§āĻž āĻāϰā§āĨ¤\n\nExpression indexes āϤāĻžā§āĻžāϤāĻžā§āĻŋ āϝā§āĻ āĻāϰāĻž āϏāĻšāĻ āĻāĻžāϰāĻŖ āĻā§āĻŦāĻŋāϞ āĻĒāϰāĻŋāĻŦāϰā§āϤāύ āĻāϰāϤ⧠āĻšā§ āύāĻžāĨ¤ āϝāĻĻāĻŋ āĻāĻĒāύāĻŋ āĻā§āĻŦāϞ āĻāϤāĻŋ āĻāĻžāύ āĻāĻŦāĻ āĻā§āϞāĻŽā§āϞ SQL āĻŽāĻžāύāϤ⧠āĻĒāĻžāϰā§āύ, āĻāĻāĻāĻŋ expression index āĻĒā§āϰāĻžāϝāĻŧāĻ āϝāĻĨā§āώā§āĻāĨ¤ āĻāĻžāϰāĻžāĻĒ āĻĻāĻŋāĻ āĻšāϞ⧠āĻĒā§āϤ⧠āĻ
āϏā§āĻŦāĻžāĻā§āĻāĻŋāĻ āĻāĻŦāĻ āĻĒā§āϞā§āϝāĻžāύāĻžāϰāĻā§ āĻāĻĒāύāĻžāϰ āĻāĻā§āϏāĻĒā§āϰā§āĻļāύā§āϰ āϏāĻ āĻŋāĻ āĻŽāĻŋāϞ āĻā§āĻāĻā§ āĻĒā§āϤ⧠āĻšāĻŦā§āĨ¤\n\nViews āĻāĻĒāĻāĻžāϰ⧠āϝāĻāύ āĻāĻĒāύāĻŋ āĻāĻžāĻāϞ⧠āĻāĻāĻāĻŋ āĻļā§ā§āĻžāϰā§āĻĄ āĻĄā§āĻāĻž-āĻāĻā§āϤāĻŋ, āĻŦāĻŋāĻļā§āώāϤ āϝāĻĻāĻŋ āĻ
ā§āϝāĻžāĻĄāĻŽāĻŋāύ āϤāĻžāϞāĻŋāĻāĻžā§ āĻ
āύā§āĻ āĻā§āĻŦāĻŋāϞ āĻā§ā§āύ āĻāϰā§āĨ¤ āĻāĻŋāύā§āϤ⧠āĻāĻāĻŋāϞ āĻāĻŋāĻ āĻĒā§āϰāĻāϞāĻŋāϤ āĻŦā§āϝā§āĻŦāĻšā§āϞ āĻāĻžāĻāĻā§ āϞā§āĻāĻŋā§ā§ āϰāĻžāĻāϤ⧠āĻĒāĻžāϰ⧠āĻāĻŦāĻ āĻĄāĻŋāĻŦāĻžāĻ āĻāϰāĻžāϰ āĻāύā§āϝ āĻāϰā§āĻāĻāĻŋ āĻāĻžā§āĻāĻž āϝā§āĻ āĻāϰā§āĨ¤\n\nTriggers āĻāĻāĻāĻŋ āϏāĻžāϧāĻžāϰāĻŖ āĻāϞāĻžāĻŽ āϏāĻŋāĻā§āĻ āϰāĻžāĻāϤ⧠āĻĒāĻžāϰā§, āĻāĻŋāύā§āϤ⧠āĻāĻā§āϞ⧠āĻŽā§āĻŦāĻžāĻāϞ āĻĒāĻžāĻāĻžāϤāύā§āϰ āĻŽāϤā§āĨ¤ āϤāĻžāϤ⧠āĻŦāĻžāϞā§āĻ āĻāĻĒāĻĄā§āĻ āϧā§āϰ āĻšāϤ⧠āĻĒāĻžāϰ⧠āĻāĻŦāĻ āĻā§āϰāĻžāĻŦāϞāĻļā§āĻ āĻāϰāĻžāϰ āϏāĻŽā§ āϏāĻšāĻā§āĻ āύāĻāϰ⧠āύāĻž āĻāϏāϤ⧠āĻĒāĻžāϰā§āĨ¤\n\nāĻāĻāύ⧠āĻāĻāύ⧠āϏāĻŦāĻā§āϝāĻŧā§ āĻāĻžāϞ⧠āĻ
āĻĒāĻļāύ āĻšāϞ⧠āĻ
ā§āϝāĻžāĻĒ āĻĻā§āĻŦāĻžāϰāĻž āĻāϰāĻž āĻāĻāĻāĻŋ āϏāĻžāϧāĻžāϰāĻŖ āĻāϞāĻžāĻŽāĨ¤ āϝāĻĻāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻāĻžāϰ⧠āĻāĻāĻžāĻā§ āϏāĻŽā§āĻĒāĻžāĻĻāύāĻž āĻāϰā§, āĻ
āĻĨāĻŦāĻž āϏā§āϤā§āϰāĻāĻŋ āĻŦāĻžāϰāĻŦāĻžāϰ āĻŦā§āϝāĻŦāϏāĻžāϝāĻŧāĻŋāĻ āϏāĻŋāĻĻā§āϧāĻžāύā§āϤ āĻĒāϰāĻŋāĻŦāϰā§āϤāĻŋāϤ āĻšā§ (āĻļā§āϧ⧠āϰ⧠āĻĄā§āĻāĻž āύā§), āϤāĻžāĻšāϞ⧠āĻāĻāĻŋ āϏā§āĻĒāώā§āĻ āϰāĻžāĻāĻž āĻāĻžāϞā§āĨ¤\n\nāĻāĻāĻāĻŋ āĻĻā§āϰā§āϤ āϏāĻŋāĻĻā§āϧāĻžāύā§āϤā§āϰ āĻāĻĒāĻžā§:\n\n- āĻĒā§āϤ⧠āϏāĻšāĻ āĻā§ā§ā§āϰāĻŋ āĻ āĻā§āĻŦāϞ āϰ⧠āĻĄā§āĻāĻžāϰ āĻāĻĒāϰ āĻāĻŋāϤā§āϤāĻŋ āĻāϰ⧠āϏā§āĻĨāĻŋāϤāĻŋāĻļā§āϞ āϏā§āϤā§āϰ āĻāĻžāύ? āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§āύ generated columnāĨ¤\n- āĻāĻāĻāĻŋ āύāĻŋāϰā§āĻĻāĻŋāώā§āĻ āĻĢāĻŋāϞā§āĻāĻžāϰā§āϰ āĻāύā§āϝ āĻāϤāĻŋ āĻāĻžāύ āĻāĻŦāĻ āĻā§āϞāĻŽā§āϞ SQL āĻŽāĻžāύāϤ⧠āĻĒāĻžāϰā§āύ? āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§āύ expression indexāĨ¤\n- āĻ
āύā§āĻ āĻāĻžā§āĻāĻžā§ āĻāĻāĻ āĻāϝāĻŧā§āύ āĻāϰāĻž āϰāĻŋāĻĒā§āϰā§āĻ-āĻāĻā§āϤāĻŋ āĻāĻžāύ? āĻāĻŋāĻ āĻŦāĻŋāĻŦā§āĻāύāĻž āĻāϰā§āύāĨ¤\n- āĻā§āϰāϏ-āĻā§āĻŦāĻŋāϞ āϞāĻāĻŋāĻ āĻŦāĻž āϏāĻžāĻāĻĄ-āĻāĻĢā§āĻā§āĻ āĻĻāϰāĻāĻžāϰ? āĻāĻā§ āĻ
ā§āϝāĻžāĻĒ āϞāĻāĻŋāĻ, āĻĒāϰ⧠āĻā§āϰāĻŋāĻāĻžāϰ āĻŦāĻŋāĻŦā§āĻāύāĻž āĻāϰā§āύāĨ¤\n\n## āϧāĻžāĻĒā§ āϧāĻžāĻĒā§: āĻāĻāĻāĻŋ generated column āϝā§āĻ āĻāϰāĻž āĻāĻŦāĻ āĻā§ā§ā§āϰāĻŋāϤ⧠āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻž\n\nāĻāĻāĻāĻž āϧā§āϰ āĻ
ā§āϝāĻžāĻĄāĻŽāĻŋāύ āϞāĻŋāϏā§āĻ āĻā§ā§ā§āϰāĻŋ āĻĻāĻŋā§ā§ āĻļā§āϰ⧠āĻāϰā§āύ āϝāĻž UI-āϤ⧠āĻāĻĒāύāĻŋ āĻ
āύā§āĻāĻŦ āĻāϰāϤ⧠āĻĒāĻžāϰā§āύāĨ¤ āϏā§āĻā§āϰāĻŋāύ⧠āϏāĻŦāĻā§ā§ā§ āĻŦā§āĻļāĻŋ āĻŦā§āϝāĻŦāĻšā§āϤ āĻĢāĻŋāϞā§āĻāĻžāϰ āĻāĻŦāĻ āϏā§āϰā§āĻāĻā§āϞ⧠āύā§āĻ āĻāϰā§āύāĨ¤ āĻĒā§āϰāĻĨāĻŽā§ āϏā§āĻ āĻāĻāĻ āĻā§ā§ā§āϰāĻŋāĻāĻž āĻāύā§āύāϤ āĻāϰā§āύāĨ¤\n\nāĻāĻāĻāĻŋ āĻāĻŖāĻŋāϤ āĻāϰāĻž āĻĢāĻŋāϞā§āĻĄ āĻŦā§āĻā§ āύāĻŋāύ āϝāĻž āĻŦāĻžāϰāĻŦāĻžāϰ āĻāĻžāĻ āĻāĻŽāĻžā§, āĻāĻŦāĻ snake_case-āĻ āϏā§āĻĒāώā§āĻāĻāĻžāĻŦā§ āύāĻžāĻŽ āĻĻāĻŋāύ āϝā§āύ āĻ
āύā§āϝāϰāĻž āĻāĻāĻŦāĻžāϰ āĻĻā§āĻā§ āϧāĻžāϰāĻŖāĻž āĻāϰāϤ⧠āĻĒāĻžāϰ⧠āϏā§āĻāĻŋ āĻā§ āϧāϰ⧠āϰāĻžāĻā§āĨ¤\n\n### 1) GENERATED āĻāϞāĻžāĻŽ āϝā§āĻ āĻāϰā§āύ (STORED)\n\nsql\nALTER TABLE customers\nADD COLUMN full_name_key text\nGENERATED ALWAYS AS (\n lower(concat_ws(' ', last_name, first_name))\n) STORED;\n\n\nāĻāύāĻĄā§āĻā§āϏ āϝā§āĻ āĻāϰāĻžāϰ āĻāĻā§ āĻŦāĻžāϏā§āϤāĻŦ āϰā§āϤ⧠āϝāĻžāĻāĻžāĻ āĻāϰā§āύ:\n\nsql\nSELECT id, first_name, last_name, full_name_key\nFROM customers\nORDER BY id DESC\nLIMIT 5;\n\n\nāĻāĻāĻāĻĒā§āĻ āĻā§āϞ āĻšāϞ⧠āĻāĻāύāĻ āĻāĻā§āϏāĻĒā§āϰā§āĻļāύ āĻ āĻŋāĻ āĻāϰā§āύāĨ¤ STORED āĻŽāĻžāύ⧠PostgreSQL āĻĒā§āϰāϤāĻŋāĻāĻŋ āĻāύāϏāĻžāϰā§āĻ āĻ āĻāĻĒāĻĄā§āĻā§ āĻāĻāĻŋ āĻāĻĒāĻĄā§āĻ āϰāĻžāĻāĻŦā§āĨ¤\n\n### 2) āĻāĻĒāύāĻžāϰ āĻ
ā§āϝāĻžāĻĄāĻŽāĻŋāύ āϏā§āĻā§āϰāĻŋāύ āĻŽāĻŋāϞ⧠āĻāĻŽāύ āĻāύāĻĄā§āĻā§āϏ āϝā§āĻ āĻāϰā§āύ\n\nāĻāĻĒāύāĻžāϰ āĻ
ā§āϝāĻžāĻĄāĻŽāĻŋāύ āϏā§āĻā§āϰāĻŋāύ āϝāĻĻāĻŋ āϏā§āĻĨāĻŋāϤāĻŋ āĻ
āύā§āϝāĻžā§ā§ āĻĢāĻŋāϞā§āĻāĻžāϰ āĻāϰ⧠āĻāĻŦāĻ āύāĻžāĻŽ āĻ
āύā§āϝāĻžā§ā§ āϏā§āϰā§āĻ āĻāϰā§, āϏā§āĻ āĻĒā§āϝāĻžāĻāĻžāϰā§āύ āĻŽā§āϞāĻžāύ⧠āĻāύāĻĄā§āĻā§āϏ āϤā§āϰāĻŋ āĻāϰā§āύ:\n\nsql\nCREATE INDEX customers_status_full_name_key_idx\nON customers (status, full_name_key);\n\n\n### 3) āĻ
ā§āϝāĻžāĻĄāĻŽāĻŋāύ āĻā§ā§ā§āϰāĻŋ āĻāĻĒāĻĄā§āĻ āĻāϰ⧠āύāϤā§āύ āĻāϞāĻžāĻŽ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§āύ\n\nāĻāĻā§ āĻšā§āϤ⧠āĻāĻĒāύāĻžāϰ ORDER BY āĻā§āϞāĻŽā§āϞ⧠āĻāĻŋāϞāĨ¤ āĻĒāϰ⧠āĻāĻāĻŋ āĻĒāϰāĻŋāώā§āĻāĻžāϰ āĻšā§ā§ āϝāĻžā§:\n\nsql\nSELECT id, status, first_name, last_name\nFROM customers\nWHERE status = 'active'\nORDER BY full_name_key ASC\nLIMIT 50 OFFSET 0;\n\n\nāĻĒā§āϰāϤāĻŋāĻĻāĻŋāύ āĻŽāĻžāύā§āώ āϝā§āĻā§āϞ⧠āĻĢāĻŋāϞā§āĻāĻžāϰ āĻāĻŦāĻ āϏā§āϰā§āĻ āĻāϰ⧠āϏā§āĻā§āϞā§āϰ āĻāύā§āϝ generated columns āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§āύ, āĻŦāĻŋāϰāϞ āϏā§āĻā§āϰāĻŋāύā§āϰ āĻāύā§āϝ āύā§āĨ¤\n\n## āĻŦāĻžāϏā§āϤāĻŦāϏāĻŽā§āĻŽāϤ āĻāύāĻĄā§āĻā§āϏāĻŋāĻ āĻĒā§āϝāĻžāĻāĻžāϰā§āύ āϝāĻž āĻŦāĻžāϏā§āϤāĻŦ āĻ
ā§āϝāĻžāĻĄāĻŽāĻŋāύ āϏā§āĻā§āϰāĻŋāύ āĻŽāĻŋāϞāĻžā§\n\nāĻ
ā§āϝāĻžāĻĄāĻŽāĻŋāύ āϏā§āĻā§āϰāĻŋāύāĻā§āϞ⧠āĻā§ā§āĻāĻāĻŋ āĻāĻāϰāĻŖ āĻŦāĻžāϰāĻŦāĻžāϰ āĻāϰā§: āĻā§ā§āĻāĻāĻŋ āĻĢāĻŋāϞā§āĻāĻžāϰ āĻāϞāĻžāĻŽ āĻĻāĻŋā§ā§ āĻĢāĻŋāϞā§āĻāĻžāϰ, āĻāĻāĻāĻŋ āĻāϞāĻžāĻŽ āĻĻāĻŋā§ā§ āϏā§āϰā§āĻ, āĻāĻŦāĻ āĻĒā§āϝāĻžāĻāĻŋāύā§āĻļāύāĨ¤ āϏāϰā§āĻŦā§āϤā§āϤāĻŽ āϏā§āĻāĻāĻĒ āϏāĻžāϧāĻžāϰāĻŖāϤ âāϏāĻŦāĻāĻŋāĻā§ āĻāύāĻĄā§āĻā§āϏ āĻāϰāĻžâ āύā§āĨ¤ āĻŦāϰāĻ āĻāĻāĻž āĻšāϞ⧠âāĻ
āϧāĻŋāĻāĻžāĻāĻļ āϏāĻžāϧāĻžāϰāĻŖ āĻā§ā§ā§āϰāĻŋāϰ āϏāĻ āĻŋāĻ āĻāĻā§āϤāĻŋ āĻāύāĻĄā§āĻā§āϏ āĻāϰāĻžāĨ¤â\n\nāĻāĻāĻāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻŋāĻ āύāĻŋā§āĻŽ: āϏāĻŦāĻā§ā§ā§ āϏāĻžāϧāĻžāϰāĻŖ āĻĢāĻŋāϞā§āĻāĻžāϰ āĻāϞāĻžāĻŽāĻā§āϞ⧠āĻĒā§āϰāĻĨāĻŽā§ āϰāĻžāĻā§āύ, āĻāĻŦāĻ āϏāĻŦāĻā§ā§ā§ āϏāĻžāϧāĻžāϰāĻŖ āϏā§āϰā§āĻ āĻāϞāĻžāĻŽāĻā§ āĻļā§āώ⧠āϰāĻžāĻā§āύāĨ¤ āĻāĻĒāύāĻŋ āϝāĻĻāĻŋ āĻŽāĻžāϞā§āĻāĻŋ-āĻā§āύā§āϝāĻžāύā§āĻ āĻšāύ, workspace_id (āĻŦāĻž āĻ
āύā§āϰā§āĻĒ) āĻĒā§āϰāĻžāϝāĻŧāĻ āĻĒā§āϰāĻĨāĻŽ āĻāϏā§: (workspace_id, status, created_at)āĨ¤\n\nāĻā§āĻā§āϏāĻ āϏāĻžāϰā§āĻ āύāĻŋāĻā§āĻ āĻāĻāĻāĻŋ āϏāĻŽāϏā§āϝāĻžāĨ¤ āĻ
āύā§āĻ āϏāĻžāϰā§āĻ āĻŦāĻā§āϏ āĻļā§āώ āĻĒāϰā§āϝāύā§āϤ ILIKE '%term%' āĻšā§ā§ āϝāĻžā§, āϝāĻž āϏāĻžāϧāĻžāϰāĻŖ btree āĻāύāĻĄā§āĻā§āϏ āĻĻāĻŋā§ā§ āĻĻā§āϰā§āϤ āĻāϰāĻž āĻāĻ āĻŋāύāĨ¤ āĻāĻāĻāĻŋ āϏāĻšāĻžā§āĻ āĻĒā§āϝāĻžāĻāĻžāϰā§āύ āĻšāĻā§āĻā§ āĻāĻāĻāĻŋ āύāϰāĻŽāĻžāϞāĻžāĻāĻāĻĄ āĻšā§āϞā§āĻĒāĻžāϰ āĻāϞāĻžāĻŽā§ āϏāĻžāϰā§āĻ āĻāϰāĻž (āĻā§āĻ āĻšāĻžāϤā§āϰ, āĻā§āϰāĻŋāĻŽ āĻāϰāĻž, āĻšā§āϤ⧠āĻāĻāϤā§āϰāĻŋāϤ)āĨ¤ āϝāĻĻāĻŋ UI āĻĒā§āϰāĻŋāĻĢāĻŋāĻā§āϏ āϏāĻžāϰā§āĻ (term%) āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāϤ⧠āĻĒāĻžāϰā§, āϤāĻžāĻšāϞ⧠āϏā§āĻ āύāϰāĻŽāĻžāϞāĻžāĻāĻāĻĄ āĻāϞāĻžāĻŽā§āϰ āĻāĻĒāϰ btree āĻāύāĻĄā§āĻā§āϏ āϏāĻžāĻšāĻžāϝā§āϝ āĻāϰāĻŦā§āĨ¤ āϝāĻĻāĻŋ āĻāĻāĻŋ āĻāύāĻā§āĻāύāϏ āϏāĻžāϰā§āĻ (%term%) āĻšāϤ⧠āĻšā§, UI āĻāĻāϰāĻŖ āĻāĻžāĻāĻā§āύ āĻāϰāĻž āĻŦāĻž āĻā§āĻ āϏāĻžāĻŦāϏā§āĻ-āĻ āϏāĻžāϰā§āĻ āϏā§āĻŽāĻžāĻŦāĻĻā§āϧ āĻāϰāĻžāϰ āĻāĻĨāĻž āĻāĻžāĻŦā§āύāĨ¤\n\nāĻāύāĻĄā§āĻā§āϏ āϝā§āĻ āĻāϰāĻžāϰ āĻāĻā§ āϏāĻŋāϞā§āĻā§āĻāĻŋāĻāĻŋāĻāĻŋ āĻā§āĻ āĻāϰā§āύāĨ¤ āϝāĻĻāĻŋ 95% āϰ⧠āĻāĻāĻ āĻā§āϝāĻžāϞ⧠āĻļā§ā§āĻžāϰ āĻāϰ⧠(āϝā§āĻŽāύ status = 'active'), āĻāĻ āĻāϞāĻžāĻŽ āĻāĻāĻž āĻāύāĻĄā§āĻā§āϏ āĻāϰāĻž āĻā§āĻŦ āϏāĻžāĻšāĻžāϝā§āϝ āĻāϰāĻŦā§ āύāĻžāĨ¤ āĻāĻāĻŋ āĻāϰāĻ āϏāĻŋāϞā§āĻā§āĻāĻŋāĻ āĻāϞāĻžāĻŽā§āϰ āϏāĻā§āĻā§ āĻĒā§ā§āĻžāϰ āĻāϰā§āύ, āĻ
āĻĨāĻŦāĻž āĻŽāĻžāĻāύā§āϰāĻŋāĻāĻŋ āĻā§āϏā§āϰ āĻāύā§āϝ āĻĒāĻžāϰāĻļāĻŋā§āĻžāϞ āĻāύāĻĄā§āĻā§āϏ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§āύāĨ¤\n\n## āĻŦāĻžāϏā§āϤāĻŦ āĻāĻĻāĻžāĻšāϰāĻŖ: āĻāĻāĻāĻŋ āĻĻā§āϰā§āϤ āĻĨāĻžāĻāĻž āĻāĻžāϏā§āĻāĻŽāĻžāϰ āĻ
ā§āϝāĻžāĻĄāĻŽāĻŋāύ āϞāĻŋāϏā§āĻ\n\nāĻāĻāĻāĻŋ āϏāĻžāϧāĻžāϰāĻŖ āĻāĻžāϏā§āĻāĻŽāĻžāϰ āĻ
ā§āϝāĻžāĻĄāĻŽāĻŋāύ āĻĒā§āĻ āĻāϞā§āĻĒāύāĻž āĻāϰā§āύ: āĻāĻāĻāĻŋ āϏāĻžāϰā§āĻ āĻŦāĻā§āϏ, āĻā§ā§āĻāĻāĻž āĻĢāĻŋāϞā§āĻāĻžāϰ (inactive, balance range), āĻāĻŦāĻ āĻāĻāĻāĻŋ sortable âLast seenâ āĻāϞāĻžāĻŽāĨ¤ āϏāĻŽā§ā§āϰ āϏāĻžāĻĨā§ āĻāĻāĻŋ āĻā§āϞāĻŽā§āϞ⧠SQL āĻšā§ā§ āϝāĻžā§: LOWER(), TRIM(), COALESCE(), āϤāĻžāϰāĻŋāĻ āĻāĻŖāύāĻž, āĻāĻŦāĻ CASE āĻŦā§āϞāĻāĻā§āϞ⧠āϏā§āĻā§āϰāĻŋāύ āĻā§ā§ā§ āĻŦāĻžāϰāĻŦāĻžāϰāĨ¤\n\nāĻāĻāĻāĻŋ āĻĒāĻĨ āĻšāϞ⧠āĻāĻ āĻĒā§āύāϰāĻžāĻŦā§āϤā§āϤ āĻāĻā§āϏāĻĒā§āϰā§āĻļāύāĻā§āϞ⧠generated columns-āĻ āĻ ā§āϞ⧠āĻĻā§ā§āĻž āϝāĻžāϤ⧠āĻāĻāĻŋ āĻĻā§āϰā§āϤ āĻ āĻĒā§āϤ⧠āϏāĻšāĻ āĻĨāĻžāĻā§āĨ¤\n\n### āĻā§āĻŦāĻŋāϞ āĻ generated āĻāϞāĻžāĻŽāĻā§āϞā§\n\nāϧāϰāĻŋ āĻāĻāĻāĻŋ customers āĻā§āĻŦāĻŋāϞ āĻāĻā§ āϝāĻžāϰ āĻŽāϧā§āϝ⧠name, email, last_seen, āĻāĻŦāĻ balance āϰā§ā§āĻā§āĨ¤ āϤāĻŋāύāĻāĻŋ āĻāĻŖāĻŋāϤ āĻāϰāĻž āĻĢāĻŋāϞā§āĻĄ āϝā§āĻ āĻāϰā§āύ:\n\n- search_key: āϏāĻžāϧāĻžāϰāĻŖ āϏāĻžāϰā§āĻā§āϰ āĻāύā§āϝ āύāϰāĻŽāĻžāϞāĻžāĻāĻ āĻāϰāĻž āĻā§āĻā§āϏāĻ\n- is_inactive: āĻāĻāĻāĻŋ āĻŦā§āϞāĻŋā§āĻžāύ āϝāĻžāϤ⧠āĻĄā§āĻ āϞāĻāĻŋāĻ āĻŦāĻžāϰāĻŦāĻžāϰ āϞā§āĻāĻž āϞāĻžāĻā§ āύāĻž\n- balance_bucket: āĻĻā§āϰā§āϤ āϏā§āĻāĻŽā§āύā§āĻā§āĻļāύā§āϰ āĻāύā§āϝ āϞā§āĻŦā§āϞ\n\nsql\nALTER TABLE customers\n ADD COLUMN search_key text\n GENERATED ALWAYS AS (\n lower(trim(coalesce(name, ''))) || ' ' || lower(trim(coalesce(email, '')))\n ) STORED,\n ADD COLUMN is_inactive boolean\n GENERATED ALWAYS AS (\n last_seen IS NULL OR last_seen < (now() - interval '90 days')\n ) STORED,\n ADD COLUMN balance_bucket text\n GENERATED ALWAYS AS (\n CASE\n WHEN balance < 0 THEN 'negative'\n WHEN balance < 100 THEN '0-99'\n WHEN balance < 500 THEN '100-499'\n ELSE '500+'\n END\n ) STORED;\n\n\nāĻāĻāύ āĻ
ā§āϝāĻžāĻĄāĻŽāĻŋāύ āĻā§ā§ā§āϰāĻŋ UI-āĻāϰ āĻŽāϤ⧠āĻĒā§āĻŦā§āĨ¤\n\n### āĻĒāĻžāĻ āϝā§āĻā§āϝ āĻĢāĻŋāϞā§āĻāĻžāϰ + āϏā§āϰā§āĻāĻŋāĻ\n\nâInactive customers, newest activity firstâ āĻšā§ā§ āϝāĻžā§:\n\nsql\nSELECT id, name, email, last_seen, balance\nFROM customers\nWHERE is_inactive = true\nORDER BY last_seen DESC NULLS LAST\nLIMIT 50;\n\n\nāĻāĻŦāĻ āĻāĻāĻāĻŋ āĻŦā§āϏāĻŋāĻ āϏāĻžāϰā§āĻ āĻšā§ā§ āϝāĻžā§:\n\nsql\nSELECT id, name, email, last_seen, balance\nFROM customers\nWHERE search_key LIKE '%' || lower(trim($1)) || '%'\nORDER BY last_seen DESC NULLS LAST\nLIMIT 50;\n\n\nāĻŦāĻžāϏā§āϤāĻŋāĻ āĻā§ āĻšāϞ⧠āϏāĻā§āĻāϤāĻŋāĨ¤ āĻāĻāĻ āĻĢāĻŋāϞā§āĻĄ āĻŦāĻšā§ āϏā§āĻā§āϰāĻŋāύ⧠āϞāĻāĻŋāĻ āĻĒā§āύāϰāĻžāĻŦā§āϤā§āϤāĻŋ āĻāĻžā§āĻžāĻ āĻāϞāĻŦā§:\n\n- āĻāĻžāϏā§āĻāĻŽāĻžāϰ āϞāĻŋāϏā§āĻ āϏāĻžāϰā§āĻ āĻŦāĻā§āϏ search_key āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻŦā§\n- âInactive customersâ āĻā§āϝāĻžāĻŦ is_inactive āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻŦā§\n- āĻŦā§āϝāĻžāϞāĻžāύā§āϏ āĻĢāĻŋāϞā§āĻāĻžāϰ āĻāĻŋāĻĒāĻā§āϞ⧠balance_bucket āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻŦā§\n\n## āϏāĻžāϧāĻžāϰāĻŖ āĻā§āϞ āĻ āĻĢāĻžāĻāĻĻ\n\nGenerated columns āĻāĻāĻāĻŋ āϏāĻšāĻ āĻā§ā§āϰ āĻŽāϤ⧠āĻĻā§āĻāĻžā§: āĻā§āĻŦāĻŋāϞ⧠āĻāĻŖāĻŋāϤ āϰāĻžāĻā§āύ āĻāĻŦāĻ āĻā§ā§ā§āϰāĻŋ āĻĒāϰāĻŋāώā§āĻāĻžāϰ āϰāĻžāĻā§āύāĨ¤ āĻāĻā§āϞ⧠āĻā§āĻŦāϞ āϤāĻāύāĻŋ āϏāĻžāĻšāĻžāϝā§āϝ āĻāϰ⧠āϝāĻāύ āϏā§āĻā§āϞ⧠āϏā§āĻā§āϰāĻŋāύ āĻāĻŋāĻāĻžāĻŦā§ āĻĢāĻŋāϞā§āĻāĻžāϰ āĻ āϏā§āϰā§āĻ āĻāϰ⧠āϤāĻžāϰ āϏāĻžāĻĨā§ āĻŽāĻŋāϞā§, āĻāĻŦāĻ āĻāĻĒāύāĻŋ āϏāĻ āĻŋāĻ āĻāύāĻĄā§āĻā§āϏ āϝā§āĻ āĻāϰā§āύāĨ¤\n\nāϏāĻŦāĻā§ā§ā§ āϏāĻžāϧāĻžāϰāĻŖ āĻā§āϞāĻā§āϞā§:\n\n- āĻāύāĻĄā§āĻā§āϏ āĻāĻžā§āĻžāĻ āĻāĻāĻŋ āĻĻā§āϰā§āϤ āĻšāĻŦā§ āĻāĻžāĻŦāĻžāĨ¤ āĻāĻŖāĻŋāϤ āĻāϰāĻž āĻŽāĻžāύāĻāĻŋ āĻŦā§ āĻĒāϰāĻŋāϏāϰ⧠āĻĢāĻŋāϞā§āĻāĻžāϰ āĻŦāĻž āϏā§āϰā§āĻ āĻāϰāĻžāϰ āĻāύā§āϝ āĻāύāĻĄā§āĻā§āϏ āĻāĻžāĻāĨ¤\n- āĻāĻ āĻāϞāĻžāĻŽā§ āĻā§āĻŦ āĻŦā§āĻļāĻŋ āϞāĻāĻŋāĻ āĻĒā§āϝāĻžāĻ āĻāϰāĻžāĨ¤ āϝāĻĻāĻŋ āĻāĻāĻāĻŋ generated column āĻāĻāĻāĻŋ āĻā§āώā§āĻĻā§āϰ āĻĒā§āϰā§āĻā§āϰāĻžāĻŽā§āϰ āĻŽāϤ⧠āĻšā§ā§ āϝāĻžā§, āĻŽāĻžāύā§āώ āϏā§āĻāĻžāϰ āĻāĻĒāϰ āύāĻŋāϰā§āĻāϰ āĻāϰāϤ⧠āĻŦāύā§āϧ āĻāϰāĻŦā§āĨ¤ āϏāĻāĻā§āώāĻŋāĻĒā§āϤ āϰāĻžāĻā§āύ āĻāĻŦāĻ āϏā§āĻĒāώā§āĻ āύāĻžāĻŽ āĻĻāĻŋāύāĨ¤\n- āĻ
-āĻāĻŽāĻŋāĻāĻā§āĻŦāϞ āĻĢāĻžāĻāĻļāύ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻžāĨ¤ PostgreSQL āϏā§āĻā§āϰāĻĄ generated column-āĻāϰ āĻāĻā§āϏāĻĒā§āϰā§āĻļāύ āĻāĻŽāĻŋāĻāĻā§āĻŦāϞ āĻšāĻā§āĻž āĻāĻžāĻ â now() āĻŦāĻž random() āĻŽāϤ āĻĢāĻžāĻāĻļāύ āϏāĻŽāϏā§āϝāĻž āĻāϰ⧠āĻŦāĻž āĻ
āύā§āĻŽā§āĻĻāĻŋāϤ āύāĻžāĻ āĻšāϤ⧠āĻĒāĻžāϰā§āĨ¤\n- āϰāĻžāĻāĻ āĻāϏā§āĻ āĻāĻĒā§āĻā§āώāĻž āĻāϰāĻžāĨ¤ āĻāύāϏāĻžāϰā§āĻ āĻ āĻāĻĒāĻĄā§āĻāĻā§āϞā§āĻā§ āĻāĻŖāĻŋāϤ āĻāϰāĻž āĻŽāĻžāύāĻāĻŋ āĻŦāĻāĻžā§ āϰāĻžāĻāϤ⧠āĻšāĻŦā§āĨ¤ āϝāĻĻāĻŋ āĻāĻŽā§āĻĒā§āϰā§āĻ āĻŦāĻž āĻāύā§āĻāĻŋāĻā§āϰā§āĻļāύ āϧā§āϰ āĻšā§ā§ āϝāĻžā§ āϤāĻŦā§ āĻĻā§āϰā§āϤ āϰāĻŋāĻĄā§āϰ āĻŽā§āϞā§āϝ āĻāĻŽā§ āϝāĻžā§āĨ¤\n- āĻāĻžāĻāĻžāĻāĻžāĻāĻŋ āĻĄā§āĻĒā§āϞāĻŋāĻā§āĻ āϤā§āϰāĻŋ āĻāϰāĻžāĨ¤ āĻāĻ āĻŦāĻž āĻĻā§āĻ āĻŽāĻžāύāĻāϰāĻŖ āĻĒā§āϝāĻžāĻāĻžāϰā§āύ āϏā§āĻā§āϝāĻžāύā§āĻĄāĻžāϰā§āĻĄāĻžāĻāĻ āĻāϰā§āύ (āϝā§āĻŽāύ āĻāĻ āύāϰāĻŽāĻžāϞāĻžāĻāĻāĻĄ āĻā§) āĻĒāĻžāĻāĻāĻāĻŋ āĻ
āύā§āϰā§āĻĒ āĻāϞāĻžāĻŽ āĻāĻŽāĻž āĻāϰāĻžāϰ āĻŦāĻĻāϞā§āĨ¤\n\nāϝāĻĻāĻŋ āĻāĻĒāύāĻžāϰ āĻ
ā§āϝāĻžāĻĄāĻŽāĻŋāύ āϞāĻŋāϏā§āĻ ILIKE '%ann%' āĻŽāϤ⧠āĻāύāĻā§āĻāύāϏ āϏāĻžāϰā§āĻ āĻāϰā§, āĻāĻāĻāĻŋ generated column āĻāĻāĻž āϤāĻž āϰāĻā§āώāĻž āĻāϰāĻŦā§ āύāĻžāĨ¤ āĻāĻŋāύā§āϤ⧠āĻĻā§āύāύā§āĻĻāĻŋāύ âāĻĢāĻŋāϞā§āĻāĻžāϰ āĻ āϏā§āϰā§āĻâ āĻāĻžāĻā§āϰ āĻāύā§āϝ generated columns āĻāĻŦāĻ āϏāĻ āĻŋāĻ āĻāύāĻĄā§āĻā§āϏ āϏāĻžāϧāĻžāϰāĻŖāϤ āĻĒāĻžāϰāĻĢāϰāĻŽā§āϝāĻžāύā§āϏāĻā§ āĻ
āύā§āĻ āĻŦā§āĻļāĻŋ āĻĒā§āϰā§āĻŦāĻžāύā§āĻŽā§āϝāĻŧ āĻāϰ⧠āϤā§āϞā§āĨ¤\n\n## āĻļāĻŋāĻĒ āĻāϰāĻžāϰ āĻāĻā§ āĻĻā§āϰā§āϤ āĻā§āĻāϞāĻŋāϏā§āĻ\n\nāĻĒāϰāĻŋāĻŦāϰā§āϤāύ āĻĒāĻžāĻ āĻžāύā§āϰ āĻāĻā§ āύāĻŋāĻļā§āĻāĻŋāϤ āĻāϰā§āύ āĻāĻŖāĻŋāϤ āĻŽāĻžāύ, āĻā§ā§ā§āϰāĻŋ, āĻāĻŦāĻ āĻāύāĻĄā§āĻā§āϏ āĻāĻā§ āĻ
āĻĒāϰā§āϰ āϏāĻā§āĻā§ āĻŽāĻŋāϞāĻā§:\n\n- āϏā§āϤā§āϰāĻāĻŋ āϏā§āĻĨāĻŋāϤāĻŋāĻļā§āϞ āĻāĻŦāĻ āĻāĻ āĻŦāĻžāĻā§āϝ⧠āϏāĻšāĻā§ āĻŦā§āĻāĻžāύ⧠āϝāĻžā§āĨ¤\n- āĻāĻĒāύāĻžāϰ āĻā§ā§ā§āϰāĻŋ āĻāϏāϞ⧠generated column WHERE āĻāĻŦāĻ/āĻ
āĻĨāĻŦāĻž ORDER BY-āĻ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāĻā§āĨ¤\n- āĻāύāĻĄā§āĻā§āϏ āĻŦāĻžāϏā§āϤāĻŦā§ āĻŦā§āϝāĻŦāĻšāĻžāϰā§āϰ āϏāĻžāĻĨā§ āĻŽā§āϞā§, āĻāĻāύ⧠āĻāĻāĻŦāĻžāϰā§āϰ āĻā§āϏā§āĻ āύā§āĨ¤\n- āĻĒā§āϰāύ⧠āϞāĻāĻŋāĻā§āϰ āϏāĻžāĻĨā§ āĻĢāϞāĻžāĻĢāϞ āϤā§āϞāύāĻž āĻāϰā§āĻā§āύ āĻāĻŋāύāĻž (NULLs, āĻĢāĻžāĻāĻāĻž āϏā§āĻā§āϰāĻŋāĻ, āĻ
āĻĻā§āĻā§āϤ āϏā§āĻĒā§āϏāĻŋāĻ, āĻŽāĻŋāĻā§āϏāĻĄ āĻā§āϏ)āĨ¤\n- āĻā§āĻŦāĻŋāϞ āĻŦā§āϝāϏā§āϤ āĻšāϞ⧠āϰāĻžāĻāĻ āĻĒāĻžāϰāĻĢāϰāĻŽā§āϝāĻžāύā§āϏ āĻā§āϏā§āĻ āĻāϰā§āĻā§āύ āĻāĻŋāύāĻž (āĻāĻŽā§āĻĒā§āϰā§āĻ, āĻŦā§āϝāĻžāĻāĻā§āϰāĻžāĻāύā§āĻĄ āĻāĻĒāĻĄā§āĻ, āĻāύā§āĻāĻŋāĻā§āϰā§āĻļāύ)āĨ¤\n\n## āĻĒāϰāĻŦāϰā§āϤ⧠āϧāĻžāĻĒ: āĻāĻĒāύāĻžāϰ āĻ
ā§āϝāĻžāĻĄāĻŽāĻŋāύ āϏā§āĻā§āϰāĻŋāύ⧠āĻāĻāĻŋ āĻĒā§āϰāϝāĻŧā§āĻ āĻāϰāĻž\n\nāĻāĻāĻāĻž āĻā§āĻ, āĻāĻā§āĻ-āĻĒā§āϰāĻāĻžāĻŦ āĻļā§āϰ⧠āĻŦā§āĻā§ āύāĻŋāύ: ⧍-ā§Š āĻāĻŋ āĻ
ā§āϝāĻžāĻĄāĻŽāĻŋāύ āϏā§āĻā§āϰāĻŋāύ āϝā§āĻā§āϞ⧠āĻŽāĻžāύā§āώ āϏāĻžāϰāĻž āĻĻāĻŋāύ āĻā§āϞ⧠āϰāĻžāĻā§ (āĻ
āϰā§āĻĄāĻžāϰ, āĻāĻžāϏā§āĻāĻŽāĻžāϰ, āĻāĻŋāĻā§āĻ)āĨ¤ āĻā§ āϧā§āϰ āϞāĻžāĻāĻā§ āύā§āĻ āĻāϰā§āύ (āĻāĻāĻāĻŋ āϤāĻžāϰāĻŋāĻ āϰā§āĻā§āĻ āĻĢāĻŋāϞā§āĻāĻžāϰ, âāĻļā§āώ āĻāĻžāϰā§āϝāĻāϞāĻžāĻĒâ āĻ
āύā§āϝāĻžāϝāĻŧā§ āϏā§āϰā§āĻ āĻāϰāĻž, āĻŽāĻŋāϞāĻŋāϤ āύāĻžāĻŽ āĻĻāĻŋā§ā§ āϏāĻžāϰā§āĻ, āϏā§āĻā§āϝāĻžāĻāĻžāϏ āϞā§āĻŦā§āϞ āĻĻā§āĻŦāĻžāϰāĻž āĻĢāĻŋāϞā§āĻāĻžāϰ)āĨ¤ āϤāĻžāϰāĻĒāϰ āĻāĻŽāύ āĻāĻāĻāĻŋ āϏāĻāĻā§āώāĻŋāĻĒā§āϤ āϏā§āĻā§āϰ āĻāĻŖāĻŋāϤ āĻāϰāĻž āĻĢāĻŋāϞā§āĻĄ āϏā§āĻā§āϝāĻžāύā§āĻĄāĻžāϰā§āĻĄāĻžāĻāĻ āĻāϰā§āύ āϝā§āĻā§āϞ⧠āĻāĻĒāύāĻŋ āϏā§āĻā§āϰāĻŋāύ āĻā§ā§ā§ āĻĒā§āύāϰāĻžā§ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāϤ⧠āĻĒāĻžāϰāĻŦā§āύāĨ¤\n\nāĻāĻāĻāĻŋ āϰā§āϞāĻāĻāĻ āĻĒā§āϞā§āϝāĻžāύ āϝāĻž āĻĒāϰāĻŋāĻŽāĻžāĻĒ āĻāϰāĻž āϏāĻšāĻ āĻāĻŦāĻ āĻāϞā§āĻā§ āĻĢā§āϞāĻž āϏāĻšāĻ:\n\n- āϏā§āĻĒāώā§āĻ āύāĻžāĻŽ āĻĻāĻŋā§ā§ generated column(s) āϝā§āĻā§āϤ āĻāϰā§āύāĨ¤\n- āϝāĻĻāĻŋ āĻāĻĒāύāĻŋ āĻŦāĻŋāĻĻā§āϝāĻŽāĻžāύ āϞāĻāĻŋāĻ āϰāĻŋāĻĒā§āϞā§āϏ āĻāϰ⧠āĻĨāĻžāĻā§āύ, āĻāĻŋāĻā§āĻā§āώāĻŖ āĻĒā§āϰāύ⧠āĻ āύāϤā§āύ āĻĒāĻžāĻļā§ āĻĒāĻžāĻļā§ āĻāĻžāϞāĻžāύāĨ¤\n- āĻŽā§āĻāύ āĻĢāĻŋāϞā§āĻāĻžāϰ āĻŦāĻž āϏā§āϰā§āĻ āĻŽā§āϞāĻžāύ⧠āĻāύāĻĄā§āĻā§āϏ āϝā§āĻ āĻāϰā§āύāĨ¤\n- āϏā§āĻā§āϰāĻŋāύā§āϰ āĻā§ā§ā§āϰāĻŋ āύāϤā§āύ āĻāϞāĻžāĻŽ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰāϤ⧠āϏā§āϝā§āĻāĻ āĻāϰā§āύāĨ¤\n- āĻāĻā§āϰ āĻ āĻĒāϰ⧠āĻŽāĻžāĻĒā§āύ (āĻā§ā§ā§āϰāĻŋ āĻāĻžāĻāĻŽ āĻāĻŦāĻ āϏā§āĻā§āϝāĻžāύ āĻāϰāĻž āϰā§), āϤāĻžāϰāĻĒāϰ āĻĒā§āϰāύ⧠āĻā§āĻžāϰā§āĻāĻ
ā§āϝāĻžāϰāĻžāĻāύā§āĻĄ āϏāϰāĻžāύāĨ¤\n\nāĻāĻĒāύāĻŋ āϝāĻĻāĻŋ AppMaster-āĻ (AppMaster) āĻāĻā§āϝāύā§āϤāϰā§āĻŖ āĻ
ā§āϝāĻžāĻĄāĻŽāĻŋāύ āĻā§āϞāϏ āĻŦāĻžāύāĻžāύ, āĻāĻ āĻāĻŖāĻŋāϤ āĻāϰāĻž āĻĢāĻŋāϞā§āĻĄāĻā§āϞ⧠āĻāĻāĻāĻŋ āĻļā§ā§āĻžāϰā§āĻĄ āĻĄā§āĻāĻž āĻŽāĻĄā§āϞ⧠āϏā§āύā§āĻĻāϰāĻāĻžāĻŦā§ āĻĢāĻŋāĻ āĻāϰā§: āĻĄāĻžāĻāĻžāĻŦā§āϏ āύāĻŋā§āĻŽ āĻŦāĻšāύ āĻāϰā§, āĻāĻŦāĻ āĻāĻĒāύāĻžāϰ UI āĻĢāĻŋāϞā§āĻāĻžāϰāĻā§āϞ⧠āϏāϰāĻžāϏāϰāĻŋ āĻāĻāĻāĻŋ āϏāϰāϞ āĻĢāĻŋāϞā§āĻĄ āύāĻžāĻŽā§āϰ āĻĻāĻŋāĻā§ āĻĒāϝāĻŧā§āύā§āĻ āĻāϰā§, āĻā§ā§ā§āϰāĻŋ āĻāĻā§āϏāĻĒā§āϰā§āĻļāύ āĻŦāĻžāϰāĻŦāĻžāϰ āύāĻž āϞā§āĻāĻžāĻāĨ¤
āĻĒā§āϰāĻļā§āύā§āϤā§āϤāϰ
Generated columns help when you keep repeating the same expression in WHERE or ORDER BY, like normalizing names, mapping statuses, or building a sorting key. Theyâre especially useful for admin lists that are opened all day and need predictable filtering and sorting.
A stored generated column is computed on insert or update and saved like a normal column, so reads can be fast and indexable. An expression index stores the result in the index without adding a new table column, but your queries still need to use the exact expression for the planner to match it.
No, not by itself. A generated column mainly makes the query simpler and makes indexing a computed value straightforward, but you still need an index that matches your common filters and sorts if you want real speedups at scale.
Usually itâs a field you filter or sort on constantly: a normalized search key, a âfull nameâ sort key, a derived boolean like is_overdue, or a ranking number that matches how people expect results to sort. Pick one value that removes repeated work from many queries, not a one-off calculation.
Start with the most common filter columns, then put the main sort key last, like (workspace_id, status, full_name_key) if that matches the screen. This lets PostgreSQL filter quickly and then return rows already ordered without extra work.
Not very. A generated column can normalize text so behavior is consistent, but ILIKE '%term%' still tends to be slow with basic btree indexes on large tables. If performance matters, prefer prefix-style search where you can, reduce the searched dataset with other filters, or adjust the UI behavior for big tables.
Stored generated columns have to be based on immutable expressions, so functions like now() typically arenât allowed and would also be conceptually wrong because the value would go stale. For time-based flags like âinactive for 90 days,â consider a normal column maintained by a job, or compute it at query time if itâs not heavily used.
Yes, but plan it like a real migration. Changing the expression means updating the schema and recomputing values for existing rows, which can take time and add write load, so do it in a controlled deployment window if the table is large.
Yes. The database has to compute and store the value on every insert and update, so heavy write workloads (imports, sync jobs) can slow down if you add too many generated fields or complex expressions. Keep expressions short, add only what you use, and measure write performance on busy tables.
Add a generated column, validate a few real rows, then add the index that matches the screenâs main filter and sort. Update the admin query to use the new column directly, and compare query time and rows scanned before and after to confirm the change helped.


