Domanda

I have a data set in a Sybase database that is modelled by the following SQL Fiddle

Using the following basic query I can extract the subsequent data:

Query:

SELECT [Scancode], [Product Name], [Store Name], [Quantity]
FROM Sales
JOIN Items
ON   Items.PK  = Sales.ITM_FK
JOIN Stores
ON   Stores.PK = Sales.STO_FK

Data:

SCANCODE    PRODUCT NAME    STORE NAME  QUANTITY
123456789   Milk            Tokyo       19
123456789   Milk            New York    28
123456789   Milk            London      37
987654321   Eggs            Tokyo       46
987654321   Eggs            New York    55
987654321   Eggs            London      64
192837465   Bread           Tokyo       73
192837465   Bread           New York    82
192837465   Bread           London      91

I would like to retrieve the data in an "item centric" format:

SCANCODE    PRODUCT NAME    Tokyo Sales  New York Sales  London Sales
123456789   Milk            19           28              37
987654321   Eggs            46           55              64
192837465   Bread           73           82              91

Is there a scalable & efficient way to retrieve data in this format?

~ Scalable means that more stores can be added without modifying the query.

È stato utile?

Soluzione 2

As MatBailie pointed out, Sybase's lack of a PIVOT function forces you to separate data presentation from data retrieval. Your options are limited to writing an inextensible kludge or restructuring the data in an intermediary application layer.

I opted to sacrificed scalability for the lack of an intermediary application layer.

My solution follows this form:

SELECT
  [Scancode],
  [Product Name], 
  MAX( CASE WHEN STO_FK = 1 THEN net.Total ELSE 0 END ) AS 'Tokyo Sales',
  MAX( CASE WHEN STO_FK = 2 THEN net.Total ELSE 0 END ) AS 'New York Sales',
  MAX( CASE WHEN STO_FK = 3 THEN net.Total ELSE 0 END ) AS 'London Sales'
FROM Items
JOIN (
  SELECT ITM_FK, STO_FK, SUM([Quantity]) AS Total
  FROM Sales
  JOIN Stores
  ON   Stores.PK = Sales.STO_FK
  GROUP BY ITM_FK, STO_FK
) AS net
ON Items.PK = net.ITM_FK
GROUP BY
  [Scancode], 
  [Product Name]

Altri suggerimenti

In SQL Server, you can do that using a dynamic SQL. You need to first build a list of stores which you'll be able to use in the pivot query dynamically.

Note: I replaced your source data with src table for simplicity.

    declare @stores as nvarchar(max)
select @stores = STUFF( (select distinct N',' + QUOTENAME([STORE NAME])
                from src 
                FOR XML PATH(N'')), 1, 1, N'')

declare @sql as nvarchar(max) = 
N'select [Scancode], [Product Name],' + @stores +
N' from
(
    select * from src
) X
pivot
(
    SUM([Quantity])
    for [Store Name] IN (' + @stores + N')
) as p'

exec sp_executesql @sql
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top