5

別のテーブルのレコードを使用して更新するテーブルがあり、あるシステム (データベース) から別のシステムに情報を引き継ぐためにこれを行っています。シナリオは少し複雑ですが、どうしても助けが必要です:-s

3 つのテーブルがあります - componentscanおよびstage_link

成分

component_id  stage_id
------------  --------
1              NULL
2              NULL
3              NULL
4              NULL
5              NULL

スキャン

scan_id  component_id  scanner_id           date_scanned
-------  ------------  ----------  -----------------------
 1         1           scanner_a    2012-01-01 07:25:15.125
 2         1           scanner_b    2012-01-02 08:14:05.456
 3         2           scanner_a    2012-01-01 12:05:45.465
 4         3           scanner_a    2012-01-01 19:45:12.536
 5         1           scanner_c    2012-01-03 23:33:54.243
 6         2           scanner_b    2012-01-02 11:59:12.545

stage_link

stage_link_id  scanner_id  stage_id
    -------     ----------  ----------  
       1         scanner_a    1   
       2         scanner_b    1    
       3         scanner_c    2    
       4         scanner_d    2    
       5         scanner_e    2   
       6         scanner_f    3  

最新のスキャンに従ってupdate、テーブルcomponentsetフィールドが必要です。stage_id各スキャンは、関連するスキャナーに応じてコンポーネントをステージに移動します。updateテーブルに次のクエリを順番に書きましたが、次componentのエラーがスローされます。

Subquery returned more than 1 value. This is not permitted when the subquery follows '='

クエリは次のとおりです。

UPDATE component
SET stage_id = (select stage_id
                from(
                    select scn.scanner_id, sl.stage_id
                    from scan scn
                    INNER JOIN stage_link sl ON scn.scanner_id = sl.scanner_id
                    where scn.date_scanned = (  select temp_a.max_date 
                                                from (  SELECT x.component_id, MAX(x.date_scanned) as max_date
                                                        FROM scan x
                                                        where component_id = x.component_id 
                                                        GROUP BY x.component_id
                                                      ) as temp_a
                                                where component_id = temp_a.component_id)
                    ) as temp_b
                )

私は取り組んでおり、言語を使用せずに、または他の言語MS SQL Serverを使用してこれを整理したいと考えています。PHP

私はこれを機能させるために1日試みましたが、まだこれを機能させる方法がありませんでした。どんな助けでも大歓迎です!

事前にどうもありがとうございました :-)

4

3 に答える 3

3

相関サブクエリを使用せずにこれを確認してください。

UPDATE  Com
SET     stage_id = Temp4.stage_id
FROM    dbo.component Com
        INNER JOIN 
        ( 
            SELECT Temp2.component_id ,SL.stage_id
            FROM   dbo.stage_link SL
            INNER JOIN (
                            SELECT component_id ,scanner_id
                            FROM   scan
                            WHERE  date_scanned IN (
                                SELECT  MaxScanDate
                                FROM    
                                ( 
                                    SELECT component_id , MAX(date_scanned) MaxScanDate
                                    FROM scan
                                    GROUP BY component_id
                                ) Temp 
                            )
                        ) Temp2 ON Temp2.scanner_id = SL.scanner_id
        ) Temp4 ON Com.component_id = Temp4.component_id

出力:

component_id stage_id
------------ -----------
1            2
2            1
3            1
4            NULL
5            NULL
于 2012-08-23T16:23:11.850 に答える
2

さて、あなたのサブクエリは複数の値を返しています。簡単な方法の 1 つは、集計を行うことです。

SET stage_id = (select max(stage_id)
. . .

考えられる理由は、最新の日付に複数のスキャンがあるためです。状況に応じて 1 つしか選択できないため、MIN または MAX で十分です。

ただし、本当の理由は、相関サブクエリに適切なエイリアスがないためだと思います。私はこれらの行だと思います:

where component_id = x.component_id
where component_id = temp_a.component_id

エイリアスを含める必要があります。おそらく次のとおりです。

where component.component_id = x.component_id
where component.component_id = temp_a.component_id

これで十分でない場合は、必要なことを説明する必要があります。クエリが最新の日付からランダム スキャンを返すようにしますか? 最新の日付ですべてのスキャンのコンポーネントを更新しますか?

これをさらに調査する必要があります。次のようなことを試してください:

select scn.scanner_id, sl.stage_id, count(*)
from scan scn INNER JOIN
     stage_link sl
     ON scn.scanner_id = sl.scanner_id join
     (SELECT x.component_id,
             MAX(x.date_scanned) as max_date
      FROM scan x
      GROUP BY x.component_id
     ) cmax
     on scn.component_id = cmax.component_id
where scn.date_scanned = cmax.maxdate 
group by scn.scanner_id, sl.stage_id
order by count(*) desc
于 2012-08-23T15:12:30.230 に答える
2

これを機能させるには、OLAP 関数が必要でした。

UPDATE Component SET Component.stage_id = Stage_Link.stage_id
FROM Component
JOIN (SELECT component_id, scanner_id, 
             ROW_NUMBER() OVER(PARTITION BY component_id 
                               ORDER BY date_scanned DESC) rownum
      FROM Scan) Scan
  ON Scan.component_id = Component.component_id
     AND Scan.rownum = 1
JOIN Stage_Link
  ON Stage_Link.scanner_id = Scan.scanner_id
WHERE Component.stage_id IS NULL

次の結果セットが生成されます。

Component
component_id   stage_id
========================
1              2
2              1
3              1
4              null
5              null

(SQL Fiddle の実際のもあります。)

于 2012-08-23T15:35:40.977 に答える