Home > database >  Use select in group by statement in Firebird
Use select in group by statement in Firebird

Time:11-27

I'm using a Firebird database which has the following tables:

ARTICULOS

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

and RANGOSTALLE

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

I want to be able to group by a substring (shortSKU) of the longSKU and be able to get for each shortSKU the corresponding ranges and prices.

like this example:

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

I'm using the following cobe but I get the error:

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 ;

The following code works, but I need to replace the "fromposition" and "ToPosition" values with the size value like the code above, and that's when I get the error message.

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 ;

For anyone interested in helping, here you have the insert data from the tables above.

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);

CodePudding user response:

Your script contains quite a few errors. After fixing them the query is rather trivial:

select substring(LongSKU from 1 for 9), 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

  • Related