0

結合を使用して 2 つのテーブルからデータを選択する必要があります。これはかなり単純で、ここで問題はありません。この問題は、参加しようとしているフィールドが 2 つの個別の外部キーとして使用されている場合に発生します (これは私が設計したものではありません)。したがって、結合する ID フィールドは正または負の数値です。

正の数値の場合は table_2 テーブルの ID_1 に関連し、負の数値の場合は table_2 テーブルの ID_2 に関連します。ただし、ID_2 は正の数になります (外部キーに負として格納されている場合でも)。明らかに、これらを強制する制約はありません-したがって、本質的には実際の外部キーではありません:/

私が使用しているSQLは次のようになり、正の数には問題ありません。

select t1.Stuff, t2.MoreStuff from table_1 t1
join table_2 t2 on t1.ID_1 = t2.ID_1
where ...

この負の側面を結合にどのように組み込むか。これは可能ですか?理想的には、自分のニーズに合わせてテーブルを変更したいのですが、どうやらこれは有効なオプションではありません。私は元気で、本当に立ち往生しています。

私が持っていた他の唯一のアイデアは、これらの奇妙なものを処理するための別のSQLステートメントです。これはすべて、C# の clr sql によって実行されています。別の SqlCommand をコードに追加すると、処理が遅くなる可能性が高いため、すべてを 1 つのコマンドにまとめたいと思います。

あなたの入力は大歓迎です、ありがとう:)

4

8 に答える 8

2

最も簡単な方法 - UNION ALL を使用してこれらのテーブルを結合します。

select t1.Stuff, t2.MoreStuff from table_1 t1
join table_2 t2 on t1.ID_1 = t2.ID_1
where t1._ID_1>0
UNION ALL
select t1.Stuff, t2.MoreStuff from table_1 t1
join table_2 t2 on abs(t1.ID_1) = t2.ID_2
where t1._ID_1<0
于 2009-07-20T14:12:39.970 に答える
2

テーブルが次のようになっているとします。

Table1 (id INT, foo INT, fk INT)

Table2 (id1 INT, id2 INT, bar VARCHAR(100))

... whereを使用fkして行を検索することができます。Table2id1id2

次に、次のように結合を実行できます。

SELECT T1.id, T1.foo, T2.bar
FROM Table1 T1 INNER JOIN Table2 T2
ON    (T1.fk > 0 AND T2.id1 = T1.fk)
   OR (T1.fk < 0 AND T2.id2 = - T1.fk)
于 2009-07-20T14:14:43.773 に答える
1

これはあまりパフォーマンスが高くありません...しかし、その後は何もありません。負のキーを正のキーに変換し、結合の条件ロジックを変換する必要があります。このような:

select t1.Stuff, t2.MoreStuff 
from table_1 t1
join table_2 t2 on (t1.ID_1 > 0 AND t1.ID_1 = t2.ID_1)
  OR (t1.ID_1 <0 AND ABS(t1.ID_1) = t2.ID_2)
where ...

t1.ID_1 を (ABS 関数を使用して) 変換しているため、インデックスを使用する可能性はありませんが、状況を考慮して実行できる最善の方法です。

于 2009-07-20T14:14:23.150 に答える
1

次のようなことができますが、スキーマ デザイナーを LART に導入した後でのみ可能です。

SELECT
    t1.stuff, COALESCE(t2a.morestuff, t2b.morestuff)
  FROM
    table_1 t1
    LEFT JOIN table_2 t2a ON (t1.id_1 > 0 AND t1.id_1 = t2a.id_1)
    LEFT JOIN table_2 t2b ON (t1.id_1 < 0 AND t1.id_1 = -1 * t2b.id_2)
  // etc

あるいは、

SELECT
    t1.stuff, t2.morestuff
  FROM
    table_1 t1
    LEFT JOIN table_2 t2 ON (
      (t1.id_1 > 0 AND t1.id_1 = t2.id_1)
      OR (t1.id_1 < 0 AND t1.id_1 = -1 * t2.id_2)
    )
  // etc

LART を覚えておいてください。これが最も重要な部分です。

于 2009-07-20T14:14:33.320 に答える
1

これを試して

DECLARE @Table TABLE(
        ID INT,
        ForeignKeyID INT
)

INSERT INTO @Table (ID,ForeignKeyID) SELECT 1, 1
INSERT INTO @Table (ID,ForeignKeyID) SELECT 2, 2
INSERT INTO @Table (ID,ForeignKeyID) SELECT 3, -1
INSERT INTO @Table (ID,ForeignKeyID) SELECT 4, -2

DECLARE @ForeignTable TABLE(
        ID_1 INT,
        ID_2 INT,
        Val VARCHAR(MAX)
)

INSERT INTO @ForeignTable (ID_1,ID_2,Val) SELECT 1, 11, '1'
INSERT INTO @ForeignTable (ID_1,ID_2,Val) SELECT 2, 22, '2'
INSERT INTO @ForeignTable (ID_1,ID_2,Val) SELECT 3, 1, '3'
INSERT INTO @ForeignTable (ID_1,ID_2,Val) SELECT 3, 2, '4'

SELECT  *
FROM    @Table t INNER JOIN
        @ForeignTable ft ON ABS(t.ForeignKeyID) =
                            CASE 
                                WHEN t.ForeignKeyID > 0
                                    THEN ft.ID_1
                                ELSE
                                    ft.ID_2
                            END
于 2009-07-20T14:17:14.300 に答える
0

それは次のようなものでなければなりません

select t1.Stuff, t2.MoreStuff from table_1 t1, table_2 t2 where (t1.ID_1 = t2.ID_1 OR t1.ID_1 = CONCAT("-",t2.ID_1)) where ...

あなたの質問を誤解したかどうかはわかりません。

于 2009-07-20T14:11:39.923 に答える
0

テーブル 2 に左結合を適用し、絶対値関数を使用することで、探しているものを達成できるはずです。

SELECT t1.Stuff, isnull(t2.MoreStuff, t2_2.MoreStuff) 
FROM table_1 t1
    LEFT JOIN table_2 t2     ON t1.ID_1 = t2.ID_1 
                             AND t1.ID_1 > 0
    LEFT JOIN table_2 t2_2   ON abs(t1.ID_2) = t2_2.ID_2 
                             AND t1.ID_2 < 0
WHERE 
   ...

ここでの注意点は、ID_1ID_2が相互に排他的でない場合、2 つのクエリ結果が得られることです。

于 2009-07-20T14:12:01.140 に答える
0
select t1.Stuff, t2.MoreStuff from table_1 t1
join table_2 t2 on t1.ID_1 = t2.ID_1 or -t1.ID_1 = t2.ID_2
where ...
于 2009-07-20T14:16:12.677 に答える