174

次の画像は、Microsoft SQL Server2008R2システムビューの一部です。画像から、との関係はの値に依存していることがsys.partitionsわかりsys.allocation_unitsますsys.allocation_units.type。それで、それらを一緒に結合するために、私はこれに似た何かを書くでしょう:

SELECT  *
FROM    sys.indexes i
        JOIN sys.partitions p
            ON i.index_id = p.index_id 
        JOIN sys.allocation_units a
            ON CASE
               WHEN a.type IN (1, 3)
                   THEN a.container_id = p.hobt_id 
               WHEN a.type IN (2)
                   THEN a.container_id = p.partition_id
               END 

しかし、上のコードは構文エラーを出します。CASEそれは声明のせいだと思います。誰かが少し説明するのを手伝ってもらえますか?


エラーメッセージを追加します。

メッセージ102、レベル15、状態1、行6'='の近くの構文が正しくありません。

これは画像です

4

10 に答える 10

278

式は、句の部分CASEから値を返します。THENあなたはそれをこうして使うことができます:

SELECT  * 
FROM    sys.indexes i 
    JOIN sys.partitions p 
        ON i.index_id = p.index_id  
    JOIN sys.allocation_units a 
        ON CASE 
           WHEN a.type IN (1, 3) AND a.container_id = p.hobt_id THEN 1
           WHEN a.type IN (2) AND a.container_id = p.partition_id THEN 1
           ELSE 0
           END = 1

戻り値を使用して何かを行う必要があることに注意してください。たとえば、1と比較します。ステートメントが代入の値を返すか、等しいかどうかをテストしようとしましたが、どちらもCASE/THEN句のコンテキストでは意味がありません。(BOOLEANデータ型の場合、同等性のテストは理にかなっています。)

于 2012-04-21T15:26:25.330 に答える
48

代わりに、両方のテーブルにJOINするだけで、SELECT句で、次のテーブルに一致するデータを返します。

このリンクを通過することをお勧めします。SQLServerの条件付き結合JOINON句のT-SQLCaseステートメント

例えば

    SELECT  *
FROM    sys.indexes i
        JOIN sys.partitions p
            ON i.index_id = p.index_id 
        JOIN sys.allocation_units a
            ON a.container_id =
            CASE
               WHEN a.type IN (1, 3)
                   THEN  p.hobt_id 
               WHEN a.type IN (2)
                   THEN p.partition_id
               END 

編集:コメントによる。

現在のように結合条件を指定することはできません。エラーがない上記のクエリを確認してください。共通の列を取り出して、条件に応じて正しい列の値を評価します。

于 2012-04-21T06:41:47.697 に答える
17

これを試して:

...JOIN sys.allocation_units a ON 
  (a.type=2 AND a.container_id = p.partition_id)
  OR (a.type IN (1, 3) AND a.container_id = p.hobt_id)
于 2012-04-21T06:40:36.530 に答える
10

2つのケースステートメントが必要だと思います。

SELECT  *
FROM    sys.indexes i
    JOIN sys.partitions p
        ON i.index_id = p.index_id 
    JOIN sys.allocation_units a
        ON 
        -- left side of join on statement
            CASE
               WHEN a.type IN (1, 3)
                   THEN a.container_id
               WHEN a.type IN (2)
                   THEN a.container_id
            END 
        = 
        -- right side of join on statement
            CASE
               WHEN a.type IN (1, 3)
                   THEN p.hobt_id
               WHEN a.type IN (2)
                   THEN p.partition_id
            END             

それの訳は:

  • CASEステートメントはENDで単一の値を返します
  • ONステートメントは2つの値を比較します
  • CASEステートメントはCASEステートメント内で比較を行っていました。CASEステートメントをSELECTに入れると、CASEステートメントがTrueまたはFalseのどちらに評価されたかを示すブール値「1」または「0」が得られると思います。
于 2018-09-18T13:36:53.130 に答える
6

はい、できます。これが例です。

SELECT a.*
FROM TableA a
LEFT OUTER JOIN TableB j1 ON  (CASE WHEN LEN(COALESCE(a.NoBatiment, '')) = 3 
                                THEN RTRIM(a.NoBatiment) + '0' 
                                ELSE a.NoBatiment END ) = j1.ColumnName 
于 2020-05-26T17:26:18.263 に答える
5

私はあなたの例を取り、それを編集しました:

SELECT  *
FROM    sys.indexes i
    JOIN sys.partitions p
        ON i.index_id = p.index_id 
    JOIN sys.allocation_units a
        ON a.container_id = (CASE
           WHEN a.type IN (1, 3)
               THEN p.hobt_id 
           WHEN a.type IN (2)
               THEN p.partition_id
           ELSE NULL
           END)
于 2018-07-18T16:06:29.807 に答える
2

これはいいですね

https://bytes.com/topic/sql-server/answers/881862-joining-different-tables-based-condition

FROM YourMainTable
LEFT JOIN AirportCity DepCity ON @TravelType = 'A' and DepFrom =  DepCity.Code
LEFT JOIN AirportCity DepCity ON @TravelType = 'B' and SomeOtherColumn = SomeOtherColumnFromSomeOtherTable
于 2016-04-27T06:22:27.240 に答える
1

ここでは、2つの異なる結果セットの違いを比較しました。

SELECT main.ColumnName, compare.Value PreviousValue,  main.Value CurrentValue
FROM 
(
    SELECT 'Name' AS ColumnName, 'John' as Value UNION ALL
    SELECT 'UserName' AS ColumnName, 'jh001' as Value UNION ALL
    SELECT 'Department' AS ColumnName, 'HR' as Value UNION ALL
    SELECT 'Phone' AS ColumnName, NULL as Value UNION ALL
    SELECT 'DOB' AS ColumnName, '1993-01-01' as Value UNION ALL
    SELECT 'CreateDate' AS ColumnName, '2017-01-01' as Value UNION ALL
    SELECT 'IsActive' AS ColumnName, '1' as Value
) main
INNER JOIN
(
    SELECT 'Name' AS ColumnName, 'Rahul' as Value UNION ALL
    SELECT 'UserName' AS ColumnName, 'rh001' as Value UNION ALL
    SELECT 'Department' AS ColumnName, 'HR' as Value UNION ALL
    SELECT 'Phone' AS ColumnName, '01722112233' as Value UNION ALL
    SELECT 'DOB' AS ColumnName, '1993-01-01' as Value UNION ALL
    SELECT 'CreateDate' AS ColumnName, '2017-01-01' as Value UNION ALL
    SELECT 'IsActive' AS ColumnName, '1' as Value
) compare
ON main.ColumnName = compare.ColumnName AND
CASE 
    WHEN main.Value IS NULL AND compare.Value IS NULL THEN 0
    WHEN main.Value IS NULL AND compare.Value IS NOT NULL THEN 1
    WHEN main.Value IS NOT NULL AND compare.Value IS NULL THEN 1
    WHEN main.Value <> compare.Value THEN 1
END = 1 
于 2017-11-04T09:41:17.553 に答える
0

ドンキーコングの例をとった。

問題は、宣言された変数を使用する必要があることです。これにより、比較する必要があるものの左側と右側を示すことができます。これは、ユーザーの選択に基づいてさまざまなフィールドをリンクする必要があるSSRSレポートをサポートするためのものです。

最初のケースでは、選択に基づいてフィールドの選択を設定し、次に、結合のために一致させる必要のあるフィールドを設定できます。

変数が異なるフィールドから選択する必要がある場合は、右側に2番目のcaseステートメントを追加できます。

LEFT OUTER JOIN Dashboard_Group_Level_Matching ON
       case
         when @Level  = 'lvl1' then  cw.Lvl1
         when @Level  = 'lvl2' then  cw.Lvl2
         when @Level  = 'lvl3' then  cw.Lvl3
       end
    = Dashboard_Group_Level_Matching.Dashboard_Level_Name
于 2019-04-24T15:48:55.177 に答える
0

条件に基づいて参加するには、少なくとも2つの方法があります。一方はもう一方よりも高速です。

declare @loopZaKosovnice int = 1
select * 
from tHE_MoveItem mi 
left join tHE_SetProdSt st on st.acIdent = mi.acIdent

-- slow
--join the_setitem si on si.acident = case when @loopZaKosovnice = 0 then mi.acident else st.acIdentChild end 

-- two times as fast
left join the_setitem si1 on @loopZaKosovnice = 0 and si1.acident = mi.acident
left join the_setitem si2 on @loopZaKosovnice = 1 and si2.acident = st.acIdentChild
join the_setitem si on si.acident = isnull (si1.acident, si2.acIdent)
于 2021-08-05T14:40:53.100 に答える