3

「ほぼ一致」でJOINを行う必要があります。これを説明する最良の方法は、例を使用することです。

CREATE TABLE Car
 (
 Vin int,
 Make nvarchar(50),
 ColorID int,
 )

CREATE TABLE Color
 (
 ColorID int,
 ColorCode nvarchar(10)
 )

CREATE TABLE ColorName
 (
 ColorID int,
 Languagecode varchar(12),
 ColorName nvarchar(50)
 )

INSERT INTO Color Values (1, 'RED CODE')
INSERT INTO Color Values (2, 'GREEN CODE')
INSERT INTO Color Values (3, 'BLUE CODE')

INSERT INTO ColorName Values (1, 'en', 'Red')
INSERT INTO ColorName Values (1, 'en-US', 'Red, my friend')
INSERT INTO ColorName Values (1, 'en-GB', 'Red, my dear')
INSERT INTO ColorName Values (1, 'en-AU', 'Red, mate')
INSERT INTO ColorName Values (1, 'fr', 'Rouge')
INSERT INTO ColorName Values (1, 'fr-BE', 'Rouge, mon ami')
INSERT INTO ColorName Values (1, 'fr-CA', 'Rouge, mon chum')

INSERT INTO Car Values (123, 'Honda', 1)

SPROC は次のようになります。

DECLARE @LanguageCode varchar(12) = 'en-US'

SELECT * FROM Car A
JOIN Color B ON (A.ColorID = B.ColorID)
LEFT JOIN ColorName C ON (B.ColorID = C.ColorID AND C.LanguageCode = @LanguageCode)

http://sqlfiddle.com/#!6/ac24d/24を参照してください(Jake に感謝します!)

ここに課題があります。SPROC パラメーター @LanguageCode が完全に一致する場合、すべて問題ありません。

部分一致でも機能するようにしたいと思います。より具体的には、たとえば、@LanguageCode が「en-NZ」であるとすると、SPROC が言語コード「en」の値を返すようにします (「en-NZ」の値がないため)。

追加の課題として、一致するものがまったくない場合は、「en」値を返したいと思います。たとえば、@LanguageCode が 'es' の場合、SPROC は 'en' 値を返します ('es' の値がないため)。

4

2 に答える 2

2

試すleft(@LanguageCode, 2) + '%'

http://sqlfiddle.com/#!6/ac24d/26

2番目の部分について-とにかく、テーブルを2回クエリする必要があります(1つのステートメントで実行できますが、1つのステートメントで2つのステートメントのようになります)。一時(または変数)テーブルにデータを挿入し、行がないかどうかを確認してから、別のクエリを作成することもできます

テーブル関数でクエリを作成しました

http://sqlfiddle.com/#!6/b7be3/5

だからあなたは書くことができます

DECLARE @LanguageCode varchar(12) = 'es'

if not exists (select * from sf_test(@LanguageCode))
    select * from sf_test('en')
else 
    select * from sf_test(@LanguageCode)

あなたも書くことができます

declare @temp table
(
    Vin int,
    Make nvarchar(50),
    ColorCode nvarchar(10)
)

insert into @temp
select * from sf_test(@LanguageCode)

if not exists (select * from @temp)
    select * from sf_test('en')
else 
    select * from @temp
于 2012-10-20T15:41:23.503 に答える
1

@Roman Pekar がコメントenで述べたように、ランキング関数を使用して、1 つのステートメントで にフォールバックすることについての追加の要求を含め、これは実際に実行できます。方法は次のとおりです。

WITH FilteredAndRanked AS (
  SELECT
    *,
    rnk = ROW_NUMBER() OVER (
      PARTITION BY ColorID
      ORDER BY CASE LanguageCode
        WHEN @LanguageCode          THEN 1
        WHEN LEFT(@LanguageCode, 2) THEN 2
        WHEN 'en'                   THEN 3
      END
    )
  FROM ColorName
  WHERE LanguageCode IN (
    @LanguageCode,
    LEFT(@LanguageCode, 2),
    'en'
  )
)
SELECT
  ...
FROM       Car               A
INNER JOIN Color             B ON (A.ColorID = B.ColorID)
LEFT  JOIN FilteredAndRanked C ON (B.ColorID = C.ColorID AND C.rnk = 1)

;

つまり、ColorNameテーブルはクエリで使用される前にフィルター処理およびランク付けされ、ランク付けが の行のみ1が結合されます。

  1. のフィルタには、との値をColorName持つ行のみが含まれます。LanguageCode@LanguageCodeLEFT(@LanguageCode, 2)'en'

  2. LEFT(@LanguageCode, 2)ランキング値は、各行に含まれる言語コードに基づいて割り当てられ@LanguageCodeます'en'

于 2012-10-21T21:30:25.423 に答える