Q:

Multiple Wildcard Counts in Same Query

One of my job functions is being responsible for mining and marketing on a large newsletter subscription database. Each one of my newsletters has four columns (newsletter_status, newsletter_datejoined, newsletter_dateunsub, and newsletter_unsubmid). 
In addition to these columns, I also have a master unsub column that our customer service dept. can update to accomodate irate subscribers who wish to be removed from all our mailings, and another column that gets updated if a hard bounce (or a set number of soft bounces) occurs called emailaddress_status. 
When I pull a count for current valid subscribers for one list I use the following syntax:
select count (*) from subscriber_db
WHERE (emailaddress_status = 'VALID' OR emailaddress_status IS NULL)
AND newsletter_status = 'Y'
and unsub = 'N' and newsletter_datejoined >= '2013-01-01';

What I'd like to have is one query that looks for all columns with %_status, with the aforementioned criteria ordered by current count size. 
I'd like for it to look like this:

etc.
I've search around the web for months looking for something similar, but other than running them in a terminal and exporting the results I've not been able to successfully get them all in one query.
I'm running PostgreSQL 9.2.3. 
A proper test case would be each aggregate total matching the counts I get when running the individual queries.
Here's my obsfucated table definition for ordinal placement, column_type, char_limit, and is_nullable.

A:

Your schema is absolutely horrifying:
24  ***_status  text        YES
25  ***_status  text        YES
26  ***_status  text        YES
27  ***_status  text        YES
28  ***_status  text        YES
29  ***_status  text        YES

where I presume the masked *** is something like the name of a publication/newsletter/etc.
You need to read about data normalization or you're going to have a problem that keeps on growing until you hit PostgreSQL's row-size limit.
Since each item of interest is in a different column the only way to solve this with your existing schema is to write dynamic SQL using PL/PgSQL's EXECUTE format(...) USING .... You might consider this as an interim option only, but it's a bit like using a pile driver to jam the square peg into the round hole because a hammer wasn't big enough. 
There are no column name wildcards in SQL, like *_status or %_status. Columns are a fixed component of the row, with different types and meanings. Whenever you find yourself wishing for something like this it's a sign that your design needs to be re-thought.
I'm not going to write an example since (a) this is an email marketing company and (b) the "obfuscated" schema is completely unusable for any kind of testing without lots of manual work re-writing it. (In future, please provide CREATE TABLE and INSERT statements for your dummy data, or better yet, a http://sqlfiddle.com/). You'll find lots of examples of dynamic SQL in PL/PgSQL - and warnings about how to avoid the resulting SQL injection risks by proper use of format - with a quick search of Stack Overflow. I've written a bunch in the past.
Please, for your sanity and the sanity of whoever else needs to work on this system, normalize your schema.
You can create a view over the normalized tables to present the old structure, giving you time to adapt your applications. With a bit more work you can even define a DO INSTEAD view trigger (newer Pg versions) or RULE (older Pg versions) to make the view updateable and insertable, so your app can't even tell that anything has changed - though this comes at a performance cost so it's better to adapt the app if possible.
Start with something like this:
CREATE TABLE subscriber (
    id serial primary key,
    email_address text not null,
    -- please read http://www.kalzumeus.com/2010/06/17/falsehoods-programmers-believe-about-names/
    -- for why I merged "fname" and "lname" into one field:
    realname text,
    -- Store birth month/year as a "date" with a "CHECK" constraint forcing it to be the 1st day
    -- of the month. Much easier to work with.
    birthmonth date,
    CONSTRAINT birthmonth_must_be_day_1 CHECK ( extract(day from birthmonth) = 1),
    postcode text,
    -- Congratulations! You made "gender" a "text" field to start with, you avoided
    -- one of the most common mistakes in schema design, the boolean/binary gender
    -- field!
    gender text,
    -- What's MSO? Should have a COMMENT ON...
    mso text,
    source text,
    -- Maintain these with a trigger. If you want modified to update when any child record
    -- changes you can do that with triggers on subscription and reducedfreq_subscription.
    created_on timestamp not null default current_timestamp,
    last_modified timestamp not null,
    -- Use the native PostgreSQL UUID type, after running CREATE EXTENSION "uuid-ossp";
    uuid uuid not null,
    uuid2 uuid not null,
    brand text,

    -- etc etc
);

CREATE TABLE reducedfreq_subscription (
    id serial primary key,
    subscriber_id integer not null references subscriber(id),
    -- Suspect this was just a boolean stored as text in your schema, in which case
    -- delete it.
    reducedfreqsub text,
    reducedfreqpref text,
    -- plural, might be a comma list? Should be in sub-table ("join table")
    -- if so, but without sample data can only guess.
    reducedfreqtopics text,
    -- date can be NOT NULL since the row won't exist unless they joined
    reducedfreq_datejoined date not null,
    reducedfreq_dateunsub date
);

CREATE TABLE subscription (
    id serial primary key,
    subscriber_id integer not null references subscriber(id),
    sub_name text not null,
    status text not null,
    datejoined date not null,
    dateunsub date
);

CREATE TABLE subscriber_activity (
    last_click  timestamptz,
    last_open   timestamptz,
    last_hardbounce timestamptz,
    last_softbounce timestamptz,
    last_successful_mailing timestamptz
);

