Link to home
Start Free TrialLog in
Avatar of Ashraf Hassanein
Ashraf Hassanein

asked on

How to convert this query to postgres

I have the following mysql command, how can I change to postgres:
DELETE pm FROM  wp_postmeta  pm LEFT JOIN  wp_posts  wp ON wp."ID" = pm.post_id WHERE wp."ID" IS NULL;

Open in new window

SOLUTION
Avatar of Phil Phillips
Phil Phillips
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Phil seems correct about the true intent.  
PostgreSQL has a non ANSI standard extension USING clause for DELETE so the equivalent syntax would be ...

DELETE FROM wp_postmeta AS pm USING wp_posts AS wp
  WHERE pm.post_id = wp."ID"  AND wp."ID"  is null;

This is the same as
delete from wp_postmeta where post_id is null;
except there would have to be entries  in wp_posts table where wp_posts.id = NULL

It is always better to catch this on input using table column NOT NULL criteria.
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
The original query is actually a left join that tells you to delete all records from left which have no counterparts in right.

Not sure about mysql approach but it's important that the predicate "null = null" in postgresql is not true. It's NULL and as such, left join on a NULL field is simply not possible. Therefore I'd say what you're looking for is:

DELETE FROM wp_postmeta WHERE NOT EXISTS 
(SELECT 1 FROM wp_posts wp WHERE wp.id = wp_postmeta.id);

Open in new window

Note that
- "NOT EXISTS" is usually faster than "NOT IN"
- you can't use alias (e.g. pm) for the table name to delete from but you can use alias in the subquery.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Ashraf Hassanein
Ashraf Hassanein

ASKER

Thank you for your support, I think that it would be better to make a select first to see the content, but when I am trying to do :
SELECT COUNT(*) FROM  wp_postmeta WHERE post_id IS NULL OR post_id NOT IN (SELECT ID FROM wp_posts);

Open in new window


I got error:
ERROR:  column "id" does not exist
LINE 1: ...a WHERE post_id IS NULL OR post_id NOT IN (SELECT ID FROM ha...

Open in new window


Although the ID is column in such table:

 \d+ wp_posts;
                                                          Table "public.wp_posts"
        Column         |            Type             |                          Modifiers                          | Storage  | Description
-----------------------+-----------------------------+-------------------------------------------------------------+----------+-------------
 ID                    | bigint                      | not null default nextval(('has_posts_seq'::text)::regclass) | plain    |
 post_author           | bigint                      | not null default 0::bigint                                  | plain    |
 post_date             | timestamp without time zone | not null default now()                                      | plain    |
 post_date_gmt         | timestamp without time zone | not null default timezone('gmt'::text, now())               | plain    |
 post_content          | text                        | not null                                                    | extended |
 post_title            | text                        | not null                                                    | extended |
 post_excerpt          | text                        | not null                                                    | extended |
 post_status           | character varying(20)       | not null default 'publish'::character varying               | extended |
 comment_status        | character varying(20)       | not null default 'open'::character varying                  | extended |
 ping_status           | character varying(20)       | not null default 'open'::character varying                  | extended |
 post_password         | character varying(20)       | not null default ''::character varying                      | extended |
 post_name             | character varying(200)      | not null default ''::character varying                      | extended |
 to_ping               | text                        | not null                                                    | extended |
 pinged                | text                        | not null                                                    | extended |
 post_modified         | timestamp without time zone | not null default now()                                      | plain    |
 post_modified_gmt     | timestamp without time zone | not null default timezone('gmt'::text, now())               | plain    |
 post_content_filtered | text                        | not null                                                    | extended |
 post_parent           | bigint                      | not null default 0::bigint                                  | plain    |
 guid                  | character varying(255)      | not null default ''::character varying                      | extended |
 menu_order            | integer                     | not null default 0                                          | plain    |
 post_type             | character varying(20)       | not null default 'post'::character varying                  | extended |
 post_mime_type        | character varying(100)      | not null default ''::character varying                      | extended |
 comment_count         | bigint                      | not null default 0::bigint                                  | plain    |
Indexes:
    "wp_posts_pkey" PRIMARY KEY, btree ("ID")
    "wp_posts_post_author" btree (post_author)
    "wp_posts_post_name" btree (post_name)
    "wp_posts_post_parent" btree (post_parent)
    "wp_posts_type_status_date" btree (post_type, post_status, post_date, "ID")
Has OIDs: no

Open in new window

The ID is reserved word so you'll probably need to use quoted form:

SELECT COUNT(*) FROM  wp_postmeta WHERE post_id IS NULL OR post_id NOT IN (SELECT "ID" FROM wp_posts);

More info: http://www.postgresql.org/docs/8.2/static/sql-syntax-lexical.html
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks I managed to execute the query successfully finally