1

の簡略化されたテーブル構造は次のPRICESとおりです。

SKU      PriceType    FromDate      ToDate        Price
..............................................................
SUR40    NONMEMBER    1900-01-01    1900-01-01    1000
SUR40    RSP          1900-01-01    1900-01-01    1500
SUR40    MEMBER       2012-07-04    2012-07-04    649
SUR40    MEMBER       2012-06-15    2012-06-15    699
SUR40    MEMBER       2012-06-01    2012-06-01    599
SUR40    MEMBER       2012-03-31    2012-03-31    699
SUR40    MEMBER       1900-01-01    1900-01-01    749

このPRICESテーブルには、すべての製品のすべての価格が格納されます。FromDateおよびToDate列は、価格が有効になる期間を指定します。null の日付 (1900-01-01 として返される) は、指定された日付にプロモーションがない場合の既定の価格です。

SKU と日付を指定すると、クエリはその日付に適用される製品の価格を返す必要があります。たとえば、2012-06-16 を使用して選択すると、次のように返されます。

SUR40    NONMEMBER    1900-01-01    1900-01-01    1000
SUR40    RSP          1900-01-01    1900-01-01    1500
SUR40    MEMBER       1900-01-01    1900-01-01    749

2012-06-15 を使用して選択すると、次が返されます。

SUR40    NONMEMBER    1900-01-01    1900-01-01    1000
SUR40    RSP          1900-01-01    1900-01-01    1500
SUR40    MEMBER       2012-06-15    2012-06-15    699

SQL サーバーは MS SQL 2008 R2 です。前回の SQL クエリを書いてからしばらく経ちましたが、これについて頭を悩ませているようには見えません。:(

どんな助けでも大歓迎です。これが私がこれまでに思いついたものです:

select SKU, PriceType, FromDate, ToDate, Price from PRICES
where SKU IN ('SUR40')
and PriceType IN ('NONMEMBER','RSP','MEMBER')
and FromDate < GETDATE()
order by PriceType, FromDate DESC

どこかにあるはずだと思いますがgroup by、失敗してもエラーメッセージを返さないWebサービスを操作することはあまり役に立ちません:(

4

3 に答える 3

2

2 番目のクエリはバグがあるようですが (日付は 749 ですが、価格 749 のレコードを省略しました`1900-01-01)、常に日付を返したいと思います1900-01-01:

select SKU, PriceType, FromDate, ToDate, Price 
from PRICES
where SKU='SUR40'
and PriceType IN ('NONMEMBER','RSP','MEMBER')
and ((FromDate='1900-01-01' AND ToDate='1900-01-01')
    OR 
     (FromDate>='2012-06-15' AND ToDate<='2012-06-15')
    )
order by PriceType, FromDate DESC

もちろん、定数値の代わりに上記のパラメーターを使用する必要があります。

これがSQLフィドルです:http://sqlfiddle.com/#!3/18cf7/4

于 2012-06-19T10:19:15.363 に答える
2

サンプルデータ:

DECLARE @PRICES TABLE (
    SKU nvarchar(10),
    PriceType nvarchar(10),
    FromDate date,
    ToDate date,
    Price int
)

INSERT @PRICES VALUES 
('SUR40'  ,  'NONMEMBER' ,   '1900-01-01'  ,  '1900-01-01'  ,  1000 ) ,
('SUR40'  ,  'RSP'        ,  '1900-01-01'  ,  '1900-01-01'  ,  1500 ) ,
('SUR40'  ,  'MEMBER'    ,   '2012-07-04'  ,  '2012-07-04'  ,  649  ) ,
('SUR40'  ,  'MEMBER'   ,    '2012-06-15'  ,  '2012-06-15' ,   699  ) ,
('SUR40'  ,  'MEMBER'   ,    '2012-06-01'  ,  '2012-06-01' ,   599  ) ,
('SUR40'  ,  'MEMBER'    ,   '2012-03-31'  ,  '2012-03-31'  ,  699  ) ,
('SUR40'  ,  'MEMBER'     ,  '1900-01-01'  ,  '1900-01-01'   , 749  )

クエリ パラメータ:

DECLARE @SKU nvarchar(10)
DECLARE @Date date

SET @SKU = 'SUR40'
SET @Date = '2012-06-15'

クエリ:

SELECT * FROM 
    (
    SELECT
        SKU,
        PriceType,
        FromDate,
        ToDate,
        Price,
        ROW_NUMBER() 
            OVER (
                PARTITION BY SKU, PriceType
                ORDER BY 
                CASE 
                    WHEN (FromDate = '1900-01-01' 
                      AND ToDate = '1900-01-01') THEN 1 
                    ELSE 0
                END ASC) rn
    FROM @PRICES
    WHERE 
        SKU = @SKU
        AND (
            (FromDate = '1900-01-01' AND ToDate = '1900-01-01')
            OR
            (FromDate <= @Date AND @Date <= ToDate)
            )
    ) Raw
WHERE rn = 1

説明、裏返しに:

  • SKU と価格タイプごとに、フォールバック行と日付一致行の両方に関心があります (存在する場合)。
  • 日付が一致する行を優先したいのでROW_NUMBER()、適切なPARTITIONandORDER BY句を使用して、日付が一致する行 (存在する場合) をフォールバック行の前に並べます。
  • これは、内部Rawクエリです。
  • Raw次に、 rownumber を持つすべての行を選択するだけです1。これは、存在する場合は日付が一致する行、または日付が一致する行がない場合はフォールバック行になります。
于 2012-06-19T10:15:57.397 に答える
0

グループ化する必要はありません。日付に制限を追加するだけです。

select SKU, PriceType, FromDate, ToDate, Price from PRICES
where SKU IN ('SUR40')
and PriceType IN ('NONMEMBER','RSP','MEMBER')
and (FromDate = '1900-01-01' or @dateToProcess between FromDate and ToDate)
order by PriceType, FromDate DESC

@dateToProcess2012-06-16または2012-06-15などになります。

于 2012-06-19T10:06:18.370 に答える