0

我目前对复杂的 sql 代码有一个奇怪的问题。这是架构:

CREATE TABLE category (
  category_id  SERIAL PRIMARY KEY,
  cat_name  CHARACTER VARYING(255)
);

CREATE TABLE items (
  item_id      SERIAL PRIMARY KEY,
  category_id  INTEGER NOT NULL,
  item_name    CHARACTER VARYING(255),
  CONSTRAINT item_category_id_fk FOREIGN KEY(category_id) REFERENCES category(category_id) ON DELETE RESTRICT
);

CREATE TABLE item_prices (
  price_id     SERIAL PRIMARY KEY,
  item_id      INTEGER NOT NULL,
  price        numeric,
  CONSTRAINT item_prices_item_id_fk FOREIGN KEY(item_id) REFERENCES items(item_id) ON DELETE RESTRICT
);

INSERT INTO category(cat_name) VALUES('Category 1');
INSERT INTO category(cat_name) VALUES('Category 2');
INSERT INTO category(cat_name) VALUES('Category 3');

INSERT INTO items(category_id, item_name) VALUES(1, 'item 1');
INSERT INTO items(category_id, item_name) VALUES(1, 'item 2');
INSERT INTO items(category_id, item_name) VALUES(1, 'item 3');
INSERT INTO items(category_id, item_name) VALUES(1, 'item 4');

INSERT INTO item_prices(item_id, price) VALUES(1, '24.10');
INSERT INTO item_prices(item_id, price) VALUES(1, '26.0');
INSERT INTO item_prices(item_id, price) VALUES(1, '35.24');

INSERT INTO item_prices(item_id, price) VALUES(2, '46.10');
INSERT INTO item_prices(item_id, price) VALUES(2, '30.0');
INSERT INTO item_prices(item_id, price) VALUES(2, '86.24');

INSERT INTO item_prices(item_id, price) VALUES(3, '94.0');
INSERT INTO item_prices(item_id, price) VALUES(3, '70.24');

INSERT INTO item_prices(item_id, price) VALUES(4, '46.10');
INSERT INTO item_prices(item_id, price) VALUES(4, '30.0');
INSERT INTO item_prices(item_id, price) VALUES(4, '86.24');

现在这里的问题是,我需要得到一个item, 它category和最新插入的item_price.

我当前的查询如下所示:

SELECT
  category.*,
  items.*,
  f.price
FROM items
LEFT JOIN category ON category.category_id = items.category_id
LEFT JOIN ( 
  SELECT 
    price_id, 
    item_id, 
    price 
  FROM item_prices
  ORDER BY price_id DESC
  LIMIT 1
) AS f ON f.item_id = items.item_id
WHERE items.item_id = 1

不幸的是,该price列返回为NULL. 我不明白的是为什么?如果您单独执行查询中的连接,它就可以正常工作。

SQLFiddle 复杂查询:
http ://sqlfiddle.com/#!1/33888/2

SQLFiddle 与连接独奏:
http ://sqlfiddle.com/#!1/33888/5

4

3 回答 3

1

内部查询仅返回一条记录,恰好不是项目 id #1。

内部查询完全运行,然后使用“as f”的结果。

我认为你想要得到的是:

SELECT
  category.*,
  items.*,
  f.max_price
FROM items
JOIN category ON category.category_id = items.category_id
JOIN (
  SELECT item_id,MAX(price) AS max_price FROM item_prices
  WHERE item_id=1
  GROUP BY item_id
  ) AS f ON f.item_id = items.item_id

请注意,WHERE 子句现在位于内部选择中 - 除了(在这种情况下)1 之外,没有必要获取其他项目的价格。这些项目按 item_id 分组,产生单行,即 item_id=1,并且是最昂贵的item_id=1 的价格。

然后将此数据连接到其他两个表。

我已将“LEFT JOIN”更改为“JOIN”,因为我们不希望其他表中的记录在内部选择中没有相应的记录。

于 2013-06-26T02:08:00.983 回答
1

我不确定问题是什么。该查询正在执行您告诉它执行的操作。

内部子查询返回最高价格 id,即 11。它的商品 id 为 4,与查询中请求的“1”不匹配。

我唯一的反应是:“当然price是空的,这就是构造查询的目的”。

于 2013-06-26T02:09:24.770 回答
1

如果你想获得每一个的最新价格item,你可以使用,Window Function因为 PostgreSQL 支持它。

下面的查询使用ROW_NUMBER()它基本上根据记录的分组和排序方式生成数字序列。

WITH records
AS
(
    SELECT  a.item_name,
            b.cat_name,
            c.price,
            ROW_NUMBER() OVER(PARTITION BY a.item_id ORDER BY c.price_id DESC) rn
    FROM    items a
            INNER JOIN category b
                ON a.category_id = b.category_id
            INNER JOIN item_prices c
                ON a.item_id = c.item_id
)
SELECT  item_name, cat_name, price
FROM    records
WHERE   rn = 1
于 2013-06-26T02:10:30.433 回答