0

My database system is PostgreSQL 8.4

The following is the example schema:

CREATE TABLE items(
  item_code varchar(20) NOT NULL PRIMARY KEY,
  item_description varchar(200),
  item_pieces_per_pack integer
);

CREATE TABLE customer_orders (
  order_id integer,
  item_code varchar(20),
  required_shipping_date date,
  quantity integer,
  PRIMARY KEY (order_id ,item_code,required_shipping_date)
);

INSERT INTO items VALUES ('AL0000063','PANETTONE CLASSICO BASSO 1KG',1);
INSERT INTO items VALUES ('AL0000064','PANDORO CLASSICO 1KG',1);
INSERT INTO items VALUES ('AL0000065','TORRONE CIOCCOLATO E NOCCIOLE 250G',4);
INSERT INTO items VALUES ('AL0000066','CANTUCCI TOSCANI 100G',6);
INSERT INTO items VALUES ('AL0000067','SAGRANTINO DI MONTEFALCO',6);
INSERT INTO items VALUES ('AL0000068','BAROLO',6);
INSERT INTO items VALUES ('AL0000069','AMARONE',6);


INSERT INTO customer_orders VALUES (1,'AL0000063','2013-12-15',5);
INSERT INTO customer_orders VALUES (1,'AL0000066','2013-12-15',15);
INSERT INTO customer_orders VALUES (1,'AL0000067','2013-12-14',15);
INSERT INTO customer_orders VALUES (2,'AL0000063','2013-12-11',25);
INSERT INTO customer_orders VALUES (2,'AL0000064','2013-12-11',25);
INSERT INTO customer_orders VALUES (2,'AL0000067','2013-12-13',25);
INSERT INTO customer_orders VALUES (3,'AL0000063','2013-12-13',25);
INSERT INTO customer_orders VALUES (3,'AL0000065','2013-12-10',10);
INSERT INTO customer_orders VALUES (3,'AL0000065','2013-12-20',10);

I need to retrieve from the table "items" only record with item_code in a array. The following query work fine:

SELECT * FROM items
WHERE item_code = ANY('{AL0000063,AL0000064,AL0000065}'::text[])

But when I use a sub query with array_agg:

SELECT * FROM items
WHERE item_code = ANY(
  SELECT array_agg(DISTINCT item_code) 
  FROM customer_orders 
  WHERE required_shipping_date BETWEEN '2013-12-01' AND '2013-12-15')

PostgreSQL raises the error:

ERROR: operator does not exist: character varying = character varying[] LINE 2: WHERE item_code = ANY( ^ HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.


Why?

1 Answer 1

3

It must be something with parsing SQL by Postgres, because with extra cast to varchar[] it works fine:

 SELECT * FROM items
WHERE item_code = ANY((
  SELECT array_agg(DISTINCT item_code)
  FROM customer_orders
  WHERE required_shipping_date BETWEEN '2013-12-01' AND '2013-12-15')::varchar[]);

Anyway, there is no need to use array in this case:

SELECT * FROM items
WHERE item_code IN (
  SELECT DISTINCT item_code
  FROM customer_orders
  WHERE required_shipping_date BETWEEN '2013-12-01' AND '2013-12-15');
3
  • Yes, I know: I don't need to use the array in this example, but in the real application i need it. In fact if I use a subquery with "IN" it is very slow, the same query with "= ANY(<ARRAY>)" is fast. Thank you very much. Commented Oct 24, 2013 at 14:11
  • Older PostgresSQL versions have performance issues with IN syntax. Have you tried to rewrite query with EXISTS ? Commented Oct 24, 2013 at 14:25
  • In fact, I haven't tried using EXISTS instead of IN. Using EXISTS performances are equivalent than with the array. Thanks again Commented Oct 25, 2013 at 11:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.