0

以下に示すように、2つのテーブルがあります。

最初のテーブル

ここに画像の説明を入力

テーブル間にそのような関係はないと考えてください。

したがって、以下に示すように、結果テーブルが次のようになる必要があります。

ここに画像の説明を入力

どうすればこれを達成できますか?

4

4 に答える 4

2

DebitNoteTable の「AcctRef」は「繰り返し列」です。

それは大きく、巨大で、ノーノーです:)

デビットテーブルは次のようになります。

Debit No  AcctRef
--------  -------
DN1       CMP1
DN1       CMP3
DN1       CMP6
...

次に、単純な「結合」を行うことができます;)

正規化の概要は次のとおりです。可能であれば、スキーマを再検討することを強くお勧めします。

できない場合、「プラン B」は次のようなプログラムを作成することになると思います。

  • すべての価格を読み取り、テーブルに保存します

  • すべての借方のすべての AcctRef を読み取ります

  • 各 AcctRef を個々の見越に解析します

  • 各見越の価格と各借方を出力します

これは事実上、データベース全体のすべてのデータを読み取り、手動で再編成することを意味します。そうするつもりなら、そもそもなぜわざわざデータベースを用意する必要があるのでしょうか?

PS: テーブルにビットマップを使用したのは残念です。テキストはもっと良かったでしょう;)

于 2012-08-17T05:13:26.770 に答える
1

これを試して:

テーブルは正規化されていないため、以下の手順を実行する必要があります。列にカンマ区切りの値を保持することはお勧めできません。テーブルに対するあらゆる種類の操作では、テーブルを分割する必要があります..

ステップ 1: accRef 列を分割するには、次の関数を作成する必要があります。

create FUNCTION [dbo].[SDF_SplitString]
(
    @sString varchar(2048),
    @cDelimiter char(1)
)
RETURNS @tParts TABLE ( part varchar(2048) )
AS
BEGIN
    if @sString is null return
    declare     @iStart int,
                @iPos int
    if substring( @sString, 1, 1 ) = @cDelimiter 
    begin
        set     @iStart = 2
        insert into @tParts
        values( null )
    end
    else 
        set     @iStart = 1
    while 1=1
    begin
        set     @iPos = charindex( @cDelimiter, @sString, @iStart )
        if @iPos = 0
                set     @iPos = len( @sString )+1
        if @iPos - @iStart > 0                  
                insert into @tParts
                values  ( substring( @sString, @iStart, @iPos-@iStart ))
        else
                insert into @tParts
                values( null )
        set     @iStart = @iPos+1
        if @iStart > len( @sString ) 
                break
    end
    RETURN

END

ステップ2:

このクエリを使用して結果を取得します

with cte as(
select * from DebitNote cross apply dbo.SDF_SplitString(AccRef,','))
select part,price,[Debit No]=STUFF((SELECT ', ' + DebitNo
           FROM cte b 
           WHERE b.part = a.part 
          FOR XML PATH('')), 1, 2, '')
FROM cte a join AccrualNote
on part=AccrualNo
GROUP BY part,price


SQL フィドルのデモ

于 2012-08-17T05:38:22.047 に答える
0

私はそれが次のようなものでなければならないと思います:

SELECT a.Accrual_No, a.Price, d.Debit_no FROM AccrualNote AS a, DebitNote as d
WHERE a.Accrual_No IN d.AccRef

次に、このクエリを使用して取得したレコードのループを作成する必要があります(phpMyAdminを使用して試してください)

(paulsm4が絶対に正しいことを確認してください。ただし、テーブル構造を変更できない可能性があります)

于 2012-08-17T05:23:58.360 に答える
0
CREATE FUNCTION [dbo].[F_Get_DebitNo] ( @AccrualNo VARCHAR(20) )
RETURNS VARCHAR(100)
AS 
BEGIN 
    DECLARE @DebitNo VARCHAR(100)
    SET @DebitNo = ''
    SELECT  @DebitNo = @DebitNo + ',' + DebitNo
    FROM    DebitNote
    WHERE   CHARINDEX(@AccrualNo, AccRef) > 0
    SELECT  @DebitNo = RIGHT(@DebitNo, LEN(@DebitNo) - 1)
    RETURN @DebitNo
END 

SQLはうまく機能します。私はすでにテストしています。以下のようにスカラー値関数を作成するだけです。

SELECT  AccrualNo ,
    Price ,
    dbo.F_Get_DebitNo(AccrualNo) FROM    AccrualNote
于 2012-08-17T05:49:29.767 に答える