2017-08-28 2 views
1

Ich versuche, eine MS-Access-Abfrage in eine Postgres-Anweisung zu konvertieren, damit ich es in SSRS verwenden kann. Scheint gut zu funktionieren, außer für die IIF-Anweisung.IIF in Postgres

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 

es gibt die folgende Meldung function iif(boolean, interval, interval) does not exist Wie würde ich dieses Problem lösen?

Antwort

5

Sie müssen die Logik auf eine CASE Anweisung umschalten. CASE-Anweisungen sind für die meisten RDBMS Standard, daher lohnt es sich zu lernen. In Ihrem Fall (Wortspiel beabsichtigt), es würde übersetzen:

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 

die viel sauberer ist suchen, da Sie nicht mit verschachtelten iif() Fragen im Zusammenhang mit Affen haben und dass alle und sollen Sie brauchen, um mehr Employeeid ist zu addieren, Liste der hartcodierten Arbeitskosten, es ist kein großes Problem.

Sie könnten auch hier ist es von Vorteil, uns die IN Zustand finden, so dass nur Sie brauchen zwei WHEN Klauseln:

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 

Auch Sie die CASE-Anweisung in die Gleichung nur, was Sie löschte bewegen könnte Nummer möchte multiplizieren mit:

(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

Super Vorschlag +1 und markiert als Antwort, jedoch. Gibt es eine Möglichkeit, in postgres eine Funktion pg_temp function zu erstellen, die sich wie ein iif in ms access verhält? (für meinen Chef) –

+1

Ich bin nicht genug vertraut mit postgres Funktionen zu sagen, wenn das möglich ist. Ich nehme an, es wäre so, aber ich würde es aus zwei Gründen vermeiden: 1) iif() ist ein Sonderling für RDBMS. Jedes RDBMS unter der Sonne verwendet CASE. Es wäre eine gute Idee, wenn Sie Ihren SQL-Standard auf CASE umstellen würden. 2) Ich wette, ein UDF wäre langsamer als etwas, das so tief in der RDBMS-Logik verankert ist wie ein CASE. – JNevill

+0

Super danke. Ich habe etwas optimiert und jetzt ist es in Produktion. –