2011-12-30 6 views
4

は、だから私は、私は、Microsoft SQL 2008で実行しています次の文があります。パラメータ

SELECT 
    'UTC' AS timezone, 
    rel.unique_id AS relay,sns.unique_id AS sensor, 
    dateadd(MINUTE, datediff(MINUTE, 0, pak.rtime)/? * ?, 0) AS time, 
    SUM(CONVERT(FLOAT,dat.data)) AS total 
    FROM sensor_data dat 
    LEFT OUTER JOIN data_package pak ON dat.package_id = pak.id 
    LEFT OUTER JOIN relays rel ON pak.relay_id = rel.id 
    LEFT OUTER JOIN sensors sns ON dat.sensor_id = sns.id 
    LEFT OUTER JOIN sensor_types typ ON sns.sensor_type = typ.id 
    WHERE typ.name = 'Volume' AND dateadd(MINUTE, datediff(MINUTE, 0, pak.rtime)/? * ?, 0) > ? AND dateadd(MINUTE, datediff(MINUTE, 0, pak.rtime)/? * ?, 0) < ? 
    GROUP BY rel.unique_id,sns.unique_id, dateadd(MINUTE, datediff(MINUTE, 0, pak.rtime)/? * ?, 0) 
    ORDER BY time,relay,sensor 

私はそうのようなのjTDS/JDBCドライバを使用してパラメータを設定した場合私は手動ですべてのそれらの中で15秒に置く場合

Caused by: java.sql.SQLException: Column 'data_package.rtime' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause. 

Parameter 1: 15 
Parameter 2: 15 
Parameter 3: 15 
Parameter 4: 15 
Parameter 5: 2011-10-31 20:00:00 
Parameter 6: 15 
Parameter 7: 15 
Parameter 8: 2011-12-29 19:00:00 
Parameter 9: 15 
Parameter 10: 15 

私はエラーを取得しますか?スペースでは、クエリはパラメータとして日付だけで完璧に機能します。

1)間隔値(この場合は15)をパラメータ化する方法はありますか(またはこの場合は15)、エスケープして準備した文になる前に検索し置換するだけですか?

2)dateadd(datediff())セクションを3回繰り返してもかまいませんか?私はWHERE句で "時間"を参照することはできませんが、どこかでそれをよりきれいにするよう指定する方法はありますか?

SELECT dateadd(MINUTE, datediff(MINUTE, 0, pak.rtime)/? * ?, 0) AS time, 

そして、あなたのグループ::のような

答えて

5

あなたの選択ルックス定数に置き換え?

GROUP BY dateadd(MINUTE, datediff(MINUTE, 0, pak.rtime)/? * ?, 0) 

、これら二つは同じです。

名前のないパラメータを使用すると問題が発生します。選択バージョンはパラメータ1と2を使用し、バージョン別のグループはパラメータ9と10を使用します.SQL Serverでは、これらのパラメータは常に同じではありません。だから、エラーを投げます。

あなたは、サブクエリ内のフィールドを計算することによって、この状況を回避することができます

left join 
     (
     select * 
     ,  dateadd(MINUTE, datediff(MINUTE, 0, pak.rtime)/? * ?, 0) as X 
     from data_package 
     ) as pak 
on  dat.package_id = pak.id 

のようにあなたが今、あなたのクエリの他の部分でpak.Xを参照することができます。Andomarはその権利である

group by 
     pak.X 
+0

サブクエリを使用する必要はありません。派生テーブルは細かい必要があります。 –

+0

@a_horse_with_no_name:派生テーブルとサブクエリの違いは何ですか? – Andomar

0

問題はあなたのGROUP BYでのパラメータの使用ですが、私は彼のソリューションが過度に複雑かもしれないと信じています。より簡単に、私は、思うだろう書くこと:

SELECT 
    'UTC' AS timezone, 
    rel.unique_id AS relay,sns.unique_id AS sensor, 
    dateadd(MINUTE, datediff(MINUTE, 0, pak.rtime)/? * ?, 0) AS time, 
    SUM(CONVERT(FLOAT,dat.data)) AS total 
    FROM sensor_data dat 
    LEFT OUTER JOIN data_package pak ON dat.package_id = pak.id 
    LEFT OUTER JOIN relays rel ON pak.relay_id = rel.id 
    LEFT OUTER JOIN sensors sns ON dat.sensor_id = sns.id 
    LEFT OUTER JOIN sensor_types typ ON sns.sensor_type = typ.id 
    WHERE typ.name = 'Volume' AND dateadd(MINUTE, datediff(MINUTE, 0, pak.rtime)/? * ?, 0) > ? AND dateadd(MINUTE, datediff(MINUTE, 0, pak.rtime)/? * ?, 0) < ? 
    GROUP BY rel.unique_id,sns.unique_id, time 
    ORDER BY time,relay,sensor 

(あなたの特定のケースでは、あなたはWHEREでまったく同じ表現を使っているので、一方、多分サブクエリ方が良いでしょう。)