在 Firebird 的 group by 语句中使用 select

Use select in group by statement in Firebird

我正在使用具有下表的 Firebird 数据库:

关节

ProductId longSKU
1 A22121000125
2 A22121000138
3 A22123001508
4 A22124002001

TALLESPORARTICULOS

ProductId position Sizes
1 1 Small
1 2 Medium
1 3 Large
1 4 Xtra Large
1 5 XXtra Large
2 1 Small
2 2 Medium
2 3 Large
2 4 Xtra Large
2 5 XXtra Large
3 1 02
3 2 04
3 3 06
3 4 08

和 兰戈斯塔尔

ProductId FromPosition ToPosition Price
1 1 3 500
1 4 5 600
2 1 3 500
2 4 5 600
3 1 4 200

我希望能够按 longSKU 的子字符串 (shortSKU) 进行分组,并能够为每个 shortSKU 获得相应的范围和价格。

像这个例子:

ShortSKU SizeFrom SizeTo Price
A221210001 small large 500
A221210001 xtra large xxtra large 600
A221230015 02 08 200

我正在使用以下 cobe,但出现错误:

Dynamic SQL Error.

SQL error code = -104. Invalid expression in the select list (not contained in either an aggregate function or the >GROUP BY clause).

CREATE OR ALTER VIEW RANGOSPARACOSTOSYPRECIOS(
SHORTSKU,
SIZEFROM,
SIZETO,
PRICE ) AS select substring(ar.codigoparticular from 1 for 10) AS SHORTSKU,
( Select TAL.SIZE 
  From tallesporarticulos TAL 
  Where TAL.productid=Ar.productid 
  and TAL.position= RT.FromPosition) as SIZEFROM,
( Select TAL.SIZE 
  From tallesporarticulos TAL 
  Where TAL.productid=Ar.productid 
  and TAL.position= RT.ToPosition) as SIZETO,
  max(RT.PRICE)
from Articulos Ar
Inner Join tallesporarticulos TA On Ar.productId = TA.productId
Inner Join rangostalle RT On AR.productId = RT.productId
GROUP BY SHORTSKU, SIZEFROM, SIZETO ;

以下代码有效,但我需要像上面的代码一样用大小值替换“fromposition”和“ToPosition”值,这就是我收到错误消息的时候。

CREATE OR ALTER VIEW RANGOSPARACOSTOSYPRECIOS(
SHORTSKU,
SIZEFROM,
SIZETO,
PRICE ) AS select substring(ar.codigoparticular from 1 for 10) AS SHORTSKU,
RT.FromPosition as SIZEFROM,
RT.ToPosition as SIZETO,
  max(RT.PRICE)
from Articulos Ar
Inner Join tallesporarticulos TA On Ar.productId = TA.productId
Inner Join rangostalle RT On AR.productId = RT.productId
GROUP BY SHORTSKU, SIZEFROM, SIZETO ;

对于任何有兴趣提供帮助的人,这里有来自上表的插入数据。

CREATE TABLE articulos (
  ProductId INTEGER PRIMARY KEY,
  LongSKU varchar(12) NOT NULL
  );

INSERT INTO articulos VALUES (1, 'A22121000125');
INSERT INTO articulos VALUES (2, 'A22121000138');
INSERT INTO articulos VALUES (3, 'A22123001508');
INSERT INTO articulos VALUES (4, 'A22124002001');

CREATE TABLE TALLESPORARTICULOS (
  ProductId INTEGER NOT NULL,
  Position INTEGER NOT NULL,
  Sizes varchar(12) NOT NULL
  );
INSERT INTO TALLESPORARTICULOS (ProductId, position, Sizes) VALUES
(1, 1, 'SMALL'),
(1, 2, 'MEDIUM'),
(1, 3, 'LARGE'),
(1, 4, 'XTRALARGE'),
(1, 1, 'XXTRALARGE'),
(2, 2, 'SMALL'),
(2, 3, 'MEDIUM'),
(2, 4, 'LARGE'),
(2, 5, 'XTRALARGE'),
(2, 5, 'XXTRALARGE'),
(3, 1, '02'),
(3, 2, '03'),
(3, 3, '04'),
(3, 4, '05');

CREATE TABLE RANGOSTALLE (
  ProductId INTEGER NOT NULL,
  FromPosition INTEGER NOT NULL,
  ToPosition INTEGER NOT NULL,
  Price double not null
  );

INSERT INTO RANGOSTALLE (ProductId,FromPosition,ToPosition,Price) VALUES 
(1, 1,3,500),
(1, 4,5,600),
(2, 1,3,500),
(2, 4,5,600),
(3, 1,4,200);

您的脚本包含不少错误。修复它们之后,查询就相当简单了:

select substring(LongSKU from 1 for 10), low.sizes, high.sizes, avg(price)
from articulos join RANGOSTALLE on articulos.ProductId = RANGOSTALLE.ProductId
join TALLESPORARTICULOS low on RANGOSTALLE.ProductId = low.ProductId and RANGOSTALLE.FromPosition = low.Prodposition
join TALLESPORARTICULOS high on RANGOSTALLE.ProductId = high.ProductId and RANGOSTALLE.ToPosition = high.Prodposition
group by 1,2,3

https://dbfiddle.uk/?rdbms=firebird_3.0&fiddle=ae54a7d897da4604396775e3ddc4b764

可以通过将分组移动到派生的 table 来优化此查询,但这种优化在很大程度上取决于实际的 table 结构和查询要求。