2017-08-28 4 views
1

私はSSRSで使用できるように、MS-Accessクエリをpostgresステートメントに変換しようとしています。 IIFの声明を除いて素晴らしい仕事をしているようだ。postgresのIIF

SELECT labor_sort_1.ncm_id 
,IIf(labor_sort_1.sortby_employeeid = 3721 
, ((labor_sort_1.MaxUpdatedAt - labor_sort_1.MinNCMScanTime) * 24 * 29 * labor_sort_1.number_of_ops) 
, IIf(labor_sort_1.sortby_employeeid = 3722 
    , ((labor_sort_1.MaxUpdatedAt - labor_sort_1.MinNCMScanTime) * 24 * 24 * labor_sort_1.number_of_ops) 
    , IIf(labor_sort_1.sortby_employeeid = 3755, ((labor_sort_1.MaxUpdatedAt - labor_sort_1.MinNCMScanTime) * 24 * 24 * labor_sort_1.number_of_ops) 
    , ((labor_sort_1.MaxUpdatedAt - labor_sort_1.MinNCMScanTime) * 24 * 17 * labor_sort_1.number_of_ops)))) AS labor_cost 
FROM 
(SELECT 
ls_sort.ncm_id 
, ls_sort.computer_name 
, ls_sort.number_of_ops 
, ls_sort.badge_scan_time 
, ls_sort.sortby_employeeid 
, Min(ls_sort.ncm_scan_time) AS MinNCMScanTime 
, Max(ls_sort.updated_at) AS MaxUpdatedAt 
FROM stone.ls_sort 
INNER JOIN stone.ls ON ls_sort.ls_id = ls.ls_id 
WHERE 1=1 
AND ls_sort.created_at Between current_date-1 And current_date 
GROUP BY ls_sort.ncm_id 
, ls_sort.computer_name 
, ls_sort.number_of_ops 
, ls_sort.badge_scan_time 
, ls_sort.sortby_employeeid 
ORDER BY ls_sort.computer_name) AS labor_sort_1 

それは function iif(boolean, interval, interval) does not exist がどのように私はこの問題を解決する、次のメッセージを返しますか?

答えて

5

ロジックをCASEステートメントに切り替える必要があります。 CASE文はほとんどのRDBMSの標準ですので、学習する価値があります。あなたのケースでは(しゃれが意図した)、それは翻訳しますと:あなたは、ネストされたiif()問題で猿に持っていないと、すべてのこととあなたがより多くの社員さんを追加する必要があるはずなので、多くクリーナー探している

CASE 
    WHEN labor_sort_1.sortby_employeeid = 3721 
     THEN (labor_sort_1.MaxUpdatedAt - labor_sort_1.MinNCMScanTime) * 24 * 29 * labor_sort_1.number_of_ops 
    WHEN labor_sort_1.sortby_employeeid = 3722 
     THEN (labor_sort_1.MaxUpdatedAt - labor_sort_1.MinNCMScanTime) * 24 * 24 * labor_sort_1.number_of_ops 
    WHEN labor_sort_1.sortby_employeeid = 3755 
     THEN (labor_sort_1.MaxUpdatedAt - labor_sort_1.MinNCMScanTime) * 24 * 24 * labor_sort_1.number_of_ops 
    ELSE 
     (labor_sort_1.MaxUpdatedAt - labor_sort_1.MinNCMScanTime) * 24 * 17 * labor_sort_1.number_of_ops) 
    END AS labor_cost 

ハードコードされた労働コストのリスト、それは大したことではありません。

また、あなたは2つのだけWHEN句必要それは、私たちに有利なここIN条件がそうするかもしれません。また

CASE 
    WHEN labor_sort_1.sortby_employeeid = 3721 
     THEN (labor_sort_1.MaxUpdatedAt - labor_sort_1.MinNCMScanTime) * 24 * 29 * labor_sort_1.number_of_ops 
    WHEN labor_sort_1.sortby_employeeid IN (3722, 3755) 
     THEN (labor_sort_1.MaxUpdatedAt - labor_sort_1.MinNCMScanTime) * 24 * 24 * labor_sort_1.number_of_ops 
    ELSE 
     (labor_sort_1.MaxUpdatedAt - labor_sort_1.MinNCMScanTime) * 24 * 17 * labor_sort_1.number_of_ops) 
    END AS labor_cost 

を、あなただけのどんな数あなたを出し式にCASE文を移動することができます乗算したい:

(labor_sort_1.MaxUpdatedAt - labor_sort_1.MinNCMScanTime) 
    * 24  
    * CASE 
     WHEN labor_sort_1.sortby_employeeid = 3721 THEN 29 
     WHEN labor_sort_1.sortby_employeeid IN (3722,3755) THEN 24 
     ELSE 17 
     END 
    * labor_sort_1.number_of_ops AS labor_cost 
+0

驚くべき示唆+ 1が答えとしてマークされています。 Postgresに関数pg_tempを作成し、msアクセスのiifと同じように動作する方法はありますか? (私の上司のために) –

+1

私はそれが可能であるかどうかを言うためにpostgres関数には十分に精通していません。私はそうするだろうと思うが、私は2つの理由でそれをやることは避けるだろう:1)iif()はRDBMSにとって奇妙なものである。太陽の下のすべてのRDBMSはCASEを使用します。 SQLをより標準化するために、CASEに切り替えることは良い考えです。 2)私は、UDFがCASEとしてRDBMSロジックに深く定着しているものよりも遅くなることを賭けている。 – JNevill

+0

ありがとうございました。私はいくつか微調整を行い、現在は生産中です。 –