4

外部キーなしでテーブルを結合するための情報を検索しようとしましたが、答えは常に外部キーを作成することです。これを行うために問題のテーブルを変更することはできません。また、既に運用されているデータについて報告する必要があります。以下は、問題を例示するために関連する表のデータの一部です。

Table A
Journal    Account    Debit    Credit    Sequence
--------------------------------------------------
87041      150-00     100.00   0.00      16384
87041      150-10     0.00     100.00    32768
87041      150-00     50.0     0.0       49152
87041      210-90     0.0      50.0      65536

次に、追加の情報を追跡する 2 番目のテーブルは、ほとんど同じですが、明細項目を適切に結び付けるシーケンス番号がありません。関係のない独自のシーケンス番号があります。

Table B
Journal    Account    Label    Artist    Sequence
--------------------------------------------------
87041      150-00     Label02  Artist12  1
87041      150-10     Label09  Artist03  2
87041      150-00     Label04  Artist01  3
87041      210-90     Label01  Artist05  4

現時点で思いつく最善の方法は、Journal と Account に参加することですが、それではレコードが重複します。私はグループ化とシーケンス番号の max() をいじって近づいてきましたが、その結果、行数が非常に多いジャーナルエントリのすべての重複が削除されるわけではなく、2 番目のテーブルからの最初の一致が常に表示されます。同じアカウントを持つ行。

Closest - but bad - result
Journal    Account    Debit    Credit    Sequence    Label    Artist
----------------------------------------------------------------------
87041      150-00     100.00   0.00      16384       Label02  Artist12
87041      150-10     0.00     100.00    32768       Label09  Artist03
87041      150-00     50.0     0.0       49152       Label02  Artist12  <-- wrong 
87041      210-90     0.0      50.0      65536       Label01  Artist05

重複が除外され、正しいレーベルとアーティストが表示されるようにテーブルを結合するにはどうすればよいですか? テーブル A の 49152 レコードが一致を探しているときに、テーブル B のレコードの 1 つが既に使用されていることを認識しているクエリを作成する必要があるように感じます。

編集:

@Justin Crabtree A.Sequence は、項目が入力された順序になります。したがって、ユーザーは例の最後の行を最初に入力し、次に最初の行、3 番目、最後に 2 番目の行を入力することができます。

@Edper Microsoft SQL Server...うーん、今朝クライアントのマシンにリモート接続できません...そうでなければ、バージョンを提供します。

@Abe Miessler はい、あなたは正しいです。

サーバーに戻ることができたらすぐに、あなたの提案を試してみます@pkuderov

4

4 に答える 4

4

これを試してください

;WITH a AS
(
    SELECT Journal,
           Account,
           Debit,
           Credit,
           Sequence,
           Id = ROW_NUMBER() OVER(PARTITION BY Journal ORDER BY Sequence)
    FROM dbo.tablea
)
, b AS
(
    SELECT Journal,
           Account,
           Label,
           Artist,
           Id = ROW_NUMBER() OVER(PARTITION BY Journal ORDER BY Sequence)
    FROM dbo.tableb
)

SELECT a.Journal,
       a.Account,
       a.Debit,
       a.Credit,
       a.Sequence,
       b.Label,
       b.Artist
FROM a
JOIN b ON b.Journal = a.Journal
      AND b.Account = a.Account
      AND b.Id = a.Id
于 2013-06-28T23:29:18.560 に答える
3

こんにちは、それは単なるアイデアです:

select
    a.Journal, a.Account, a.Debit, a.Credit, a.Sequence, b.Label, b.Artist
from (
    select
        *, 
        row_number() over(partition by Journal, Account order by Sequence) as idInGroup
    from a
) as a
join (
    select
        *, 
        row_number() over(partition by Journal, Account order by Sequence) as idInGroup
    from b
) as b on
    a.Journal = b.Journal
    and a.Account = b.Account
    and a.idInGroup = b.idInGroup

ここでは、順序が (両方のテーブルで) 順序で表示され、それが結合テーブルの基本的なヒントであると仮定します。

于 2013-06-28T23:25:26.400 に答える
0

要件を正しく読んでいて、テーブル A のすべての行が必要で、テーブル B の最初の一致する行のみが必要な場合は、TOP(1) で OUTER APPLY を実行することをお勧めします。それは次のようになります。

select *
from TableA
OUTER APPLY
 (select TOP(1) Journal, Account, Label, Artist, Sequence
  FROM TableB
  WHERE Journal = TableA.Journal AND Account = TableA.Account
  ORDER BY Sequence) as B

(間違いなく疑似コードですが、多少近いはずです。)

結局のところ、ROW_NUMBER() を使用して、Journal と Account でパーティション化し、各結果セットの Row_Number 値に一致させることができます。TableA に対して 1 つのサブクエリ/CTE を生成し、TableB に対して別の CTE を生成します。それぞれに、基本的に新しいシーケンス整数である RowNumber 値があります。TableA の最初の行は TableB の最初の行と一致し、TableA の 2 番目の行は TableB の 2 番目の行と一致します。 「B」にあります。

より適切な質問は、「TableA と TableB を結び付けるデータ列を使用できない場合、コードはどのようにして TableA と TableB のすべての一致を判断するのですか?」ということです。

于 2013-06-29T01:31:34.810 に答える