I moved the function to Postgres. In MS SQL, it was executed in less than a second. In Postgresql, it runs for almost 6 minutes. I've been working on this problem for 6 hours, and I haven't found a reason. As I understand it, the problem is in the syntax.
In the xt_ed_registr_grp_led function, I attach the function (xt_ef_registr_pts_all) to a table in this format:
LEFT JOIN dbo.xt_ef_registr_pts_all(_D_Date, -1, NULL) AS RP_Child
ON RP_Child.link = RG.f_registr_pts
Next, I attach the code from MS SQL and Postgres.
Postgres function
...
AS
$$
BEGIN
RETURN QUERY SELECT
RP.link,
RP.f_division,
RP.f_subdivision,
RP.f_subscr,
RP.f_sale_items,
RP.f_sale_category,
RP.d_date_begin,
RP.d_date_end,
RCap.f_work_modes AS F_Work_Modes,
RP.f_energy_levels,
NP.f_conn_points,
NP.c_address_short,
CASE
WHEN COALESCE(Provinces.c_name, '') = ''
THEN NULL
ELSE LTRIM(RTRIM((COALESCE(LT_Provinces.c_prefix || ' ', '') || COALESCE(Provinces.c_name, ''))))
END AS C_Provinces,
CASE
WHEN COALESCE(Towns.c_name, '') = ''
THEN NULL
ELSE LTRIM(RTRIM((COALESCE(LT_Towns.c_prefix || ' ', '') || COALESCE(Towns.c_name, ''))))
END AS C_Towns,
CASE
WHEN COALESCE(Municipalities.c_name, '') = ''
THEN NULL
ELSE LTRIM(RTRIM((COALESCE(LT_Municipalities.c_prefix || ' ', '') || COALESCE(Municipalities.c_name, ''))))
END AS C_Municipalities,
CASE
WHEN LTRIM(RTRIM(((COALESCE(LT_Streets.c_prefix || ' ', '') || COALESCE(Streets.c_name, '')) || COALESCE(', ' || CP.c_building_num, '') ||
COALESCE(COALESCE(' ' || sbct.c_short_name, ' ' || sbct.c_name, '/') || CP.c_building_corp, '')))) = ''
THEN NULL
ELSE LTRIM(RTRIM(((COALESCE(LT_Streets.c_prefix || ' ', '') || COALESCE(Streets.c_name, '')) || COALESCE(', ' || CP.c_building_num, '') ||
COALESCE(COALESCE(' ' || sbct.c_short_name, ' ' || sbct.c_name, '/') || CP.c_building_corp, ''))))
END AS C_Street_Building,
RCM.f_calc_methods,
RCM.d_date AS D_Calc_Methods_Date,
CASE
WHEN EXISTS(SELECT
0
FROM dbo.ed_registr_grp RG1
WHERE RG1.f_registr_pts_main = RP.link
)
THEN TRUE
ELSE FALSE
END AS B_Group,
CASE
WHEN EXISTS(SELECT
0
FROM dbo.ed_registr_grp RG1
WHERE RG1.f_registr_pts = RP.link
)
THEN TRUE
ELSE FALSE
END AS B_IncludeGroup,
dbo.xt_ef_registr_pts_energy_categ(RP.f_sale_items, RP.f_tariff, RP.f_energy_levels) AS F_Energy_Category,
RP.f_registr_pts_prev,
D.link AS F_Device,
EDP.f_division AS f_device_division,
D.n_rate,
D.n_rate * dbo.ui_ef_device_transf_rate(D.f_division, D.link, COALESCE(_D_Date, NOW())) AS N_Ktf,
Dig.c_digits,
EDC.c_name AS C_Device_Category_Name,
EDC.f_class,
D.f_device_types,
D.c_serial_number,
EDP.f_energy_types,
EDP.n_percent2,
EDP.b_main AS B_Device_Main,
D.d_setup_date,
D.d_replace_date,
EDP.n_percent,
RPT.f_tariff,
RPT.d_date::timestamptz(0)::text AS D_Tariff_Date,
RPT.f_norms,
RCon.n_cons AS N_Cons_Cons,
RCon.n_cons2 AS N_Cons_Cons2,
RCon.d_date AS D_Cons_Date,
RCap.n_cap AS N_Cap_Cons,
RCap.n_cap2 AS N_Cap_Cons2,
RCap.n_cap3 AS N_Cap_Cons3,
RCap.d_date AS D_Cap_Date,
RPA.n_rate AS N_Activity_Rate,
RPA.d_date AS D_Activity_Date,
RP.c_code AS n_code,
RP.c_name,
RP.f_balance_types,
RP.f_balance_type_details,
RP.f_balance_types_sec,
RP.f_balance_type_details_sec,
RP.n_order,
RP.b_non_heat_formula,
RP.b_line_formula,
RP.b_transf_formula,
RP.f_transf_types,
SDA.link AS F_Areas,
erpa.d_date AS D_Areas_Date,
RP.b_notinclude,
RP.f_form_46,
RP.f_cons_category,
RP.s_owner,
RP.s_create_date,
RP.s_modif_date,
RP.s_creator,
NP.link AS F_Network_Pts,
NP.c_code AS C_Network_Pts_Code,
NR.c_network_path AS _Bound_F_Network_Pts,
NR.c_network_path_short AS C_Network_Path_Short,
CASE
WHEN NIP.f_parent IS NOT NULL
THEN dbo.cf_get_network_name(COALESCE(NI_P.f_networks, NI.f_networks))
END AS _Bound_F_Network,
FSI.c_name AS _Bound_F_Sale_Items,
EDT.c_name || COALESCE(' / ' || EDT.c_modification, '') AS _Bound_F_Device_Types,
(dbo.cf_get_c_codename(FT.n_code, FT.c_name) || ' / ' || CAST(COALESCE(FTH.n_tariff, '0') AS text) || 'р.') AS _Bound_F_Tariff,
FTH.n_tariff AS N_Tariff1,
FTH.n_tariff_2 AS N_Tariff2,
EEL.c_name AS _Bound_F_Energy_Levels,
ECM.c_name || COALESCE(' / ' || ECM2.c_name, '') AS _Bound_F_Calc_Methods,
COALESCE(EBT.c_short_name, EBT.c_name) AS _Bound_F_Balance_Types,
COALESCE(EET.c_short_name, EET.c_name) AS _Bound_F_Energy_Types,
ESWM.c_name AS _Bound_F_Work_Modes,
ELA.c_name AS _Bound_F_Transf_Algorithms,
ELA2.c_name AS _Bound_F_Line_Algorithms,
ELA3.c_name AS _Bound_F_Non_Heat_Algorithms,
SDA.c_name AS _Bound_F_Areas,
CP.c_code_cp AS N_Conn_Points_Code,
COALESCE(CP.c_name, NP.c_address_short) AS C_Conn_Points_Name,
COALESCE(CPS.c_name, '') || COALESCE(' ' || CT.c_name_short, '') || COALESCE(' № ' || CPS.c_premise_number, '') AS C_Conn_Points_Sub_Name,
CPS.c_premise_number AS C_Premise_Number,
COALESCE((CPS.j_custom ->> 'j_b_dryers')::bool, (CP.j_custom ->> 'j_b_dryers')::bool) AS B_Polotenchik,
COALESCE((CPS.j_custom ->> 'j_b_riser_insulation')::bool, (CP.j_custom ->> 'j_b_riser_insulation')::bool) AS B_Isolation,
COALESCE((CPS.j_custom ->> 'j_b_external_gvs')::bool, (CP.j_custom ->> 'j_b_external_gvs')::bool) AS B_OuterGVS,
CP.f_conn_types AS F_Conn_Types,
CP.f_conn_status_types AS F_Conn_Status_Types,
FSC.c_name AS _Bound_F_Sale_Category,
ETT.c_name AS _Bound_F_Transf_Types,
FN.c_name AS _Bound_F_Norms,
dbo.cf_get_network_name(COALESCE(NI_P.f_networks, NI.f_networks)) AS C_Network_Path,
RP.n_graph_form,
RP.n_line_loss,
RP.n_rp_loss,
NP.f_conn_points_sub,
RPL_Non_Heat.d_date_begin AS D_Non_Heat_Date,
RPL_Non_Heat.n_value AS N_Non_Heat_Waste,
RPL_Non_Heat.f_loss_algorithms AS F_Non_Heat_Algorithms,
RPL_Line.d_date_begin AS D_Line_Date,
RPL_Line.n_value AS N_Line_Waste,
RPL_Line.f_loss_algorithms AS F_Line_Algorithms,
RPL_Transf.d_date_begin AS D_Transf_Date,
RPL_Transf.n_value AS N_Transf_Waste,
RPL_Transf.f_loss_algorithms AS F_Transf_Algorithms,
s.n_code AS N_Code_Subscr,
p.c_name1 AS C_Name_Subscr
FROM dbo.ed_registr_pts AS RP
LEFT JOIN dbo.sd_subscr AS s
ON s.link = RP.f_subscr
LEFT JOIN dbo.cd_partners AS p
ON p.link = s.f_partners
LEFT JOIN dbo.ed_network_pts AS NP
ON NP.link = RP.f_network_pts
AND NP.b_pod = TRUE
LEFT JOIN LATERAL
( SELECT
NIPX.link,
NIPX.f_parent
FROM dbo.ed_network_struct NIPX
WHERE NIPX.f_child = NP.link
AND NIPX.b_pod = TRUE
AND NIPX.b_ismain = TRUE
AND NIPX.d_date_begin <= COALESCE(_D_Date, NOW())
ORDER BY
NIPX.d_date_begin DESC
LIMIT 1
) AS NIP
ON TRUE
LEFT JOIN LATERAL
(
SELECT
NIPX.link,
NIPX.f_parent
FROM dbo.ed_network_struct NIPX
WHERE NIPX.f_child = NP.f_network_pts
AND NIPX.b_pod = TRUE
AND NIPX.b_ismain = TRUE
AND NIPX.d_date_begin <= COALESCE(_D_Date, NOW())
ORDER BY
NIPX.d_date_begin DESC
LIMIT 1
) AS NIP_P
ON TRUE
LEFT JOIN LATERAL
(
SELECT
NRi.id,
NRi.c_network_path,
NRi.c_network_path_short
FROM dbo.ed_network_routes NRi
WHERE NRi.n_level = 0
AND NRi.link = COALESCE(NIP_P.f_parent, NIP.f_parent)
AND NOW() >= NRi.d_date0
AND NOW() < NRi.d_date1
ORDER BY
NRi.n_rate,
NRi.d_date1,
NRi.b_main DESC
LIMIT 1
) AS NR
ON TRUE
LEFT JOIN dbo.ed_network_pts NI
ON NI.link = NIP.f_parent
AND NI.b_pod = FALSE
LEFT JOIN dbo.ed_network_pts NI_P
ON NI_P.link = NIP_P.f_parent
AND NI_P.b_pod = FALSE
/* Объект и адрес */
LEFT JOIN dbo.sd_conn_points CP
ON CP.link = NP.f_conn_points
LEFT JOIN dbo.sd_conn_points_sub CPS
ON CPS.link = NP.f_conn_points_sub
LEFT JOIN dbo.cs_conn_types CT
ON CT.link = CPS.f_conn_types
LEFT JOIN dbo.ss_building_corp_type sbct
ON sbct.link = CP.f_building_corp_type
LEFT JOIN dbo.ss_locations AS Provinces
ON Provinces.link = CP.f_provinces_fias
LEFT JOIN dbo.ss_location_types AS LT_Provinces
ON LT_Provinces.link = Provinces.f_location_types
LEFT JOIN dbo.ss_locations AS Towns
ON Towns.link = CP.f_towns_fias
LEFT JOIN dbo.ss_location_types AS LT_Towns
ON LT_Towns.link = Towns.f_location_types
LEFT JOIN dbo.ss_locations AS Municipalities
ON Municipalities.link = CP.f_municipalities_fias
LEFT JOIN dbo.ss_location_types AS LT_Municipalities
ON LT_Municipalities.link = Municipalities.f_location_types
LEFT JOIN dbo.ss_locations AS Streets
ON Streets.link = CP.f_streets_fias
LEFT JOIN dbo.ss_location_types AS LT_Streets
ON LT_Streets.link = Streets.f_location_types /* Параметры ТУ */
LEFT JOIN dbo.ed_registr_pts_areas AS erpa
ON erpa.f_registr_pts = RP.link
AND erpa.d_date <= COALESCE(_D_Date, NOW())
AND erpa.d_date_end > COALESCE(_D_Date, NOW())
LEFT JOIN dbo.sd_areas AS SDA
ON SDA.link = erpa.f_areas
LEFT JOIN dbo.ed_registr_pts_loss AS RPL_Line
ON RPL_Line.f_registr_pts = RP.link
AND RPL_Line.f_loss_types = 1
AND COALESCE(_D_Date, NOW()) BETWEEN RPL_Line.d_date_begin AND RPL_Line.d_date_end
LEFT JOIN dbo.ed_registr_pts_loss AS RPL_Transf
ON RPL_Transf.f_registr_pts = RP.link
AND RPL_Transf.f_loss_types = 2
AND COALESCE(_D_Date, NOW()) BETWEEN RPL_Transf.d_date_begin AND RPL_Transf.d_date_end
LEFT JOIN dbo.ed_registr_pts_loss AS RPL_Non_Heat
ON RPL_Non_Heat.f_registr_pts = RP.link
AND RPL_Non_Heat.f_loss_types = 3
AND COALESCE(_D_Date, NOW()) BETWEEN RPL_Non_Heat.d_date_begin AND RPL_Non_Heat.d_date_end
LEFT JOIN LATERAL
(
SELECT
RPA1.n_rate,
RPA1.d_date,
RPA1.f_registr_pts
FROM dbo.ed_registr_pts_activity AS RPA1
WHERE RPA1.f_registr_pts = RP.link
AND RPA1.d_date <= COALESCE(_D_Date, NOW())
ORDER BY
d_date DESC
LIMIT 1
) AS RPA
ON TRUE
LEFT JOIN dbo.ed_registr_pts_tariff AS RPT
ON RPT.f_registr_pts = RP.link
AND COALESCE(_D_Date, NOW()) BETWEEN RPT.d_date AND RPT.d_date_end
LEFT JOIN dbo.fs_tariff AS FT
ON FT.link = RPT.f_tariff
LEFT JOIN LATERAL
(
SELECT
FTH.n_tariff,
FTH.n_tariff_2
FROM dbo.fs_tariff_history FTH
WHERE FTH.f_tariff = FT.link
AND FTH.b_default = TRUE
AND COALESCE(_D_Date, NOW()) BETWEEN FTH.d_date_begin AND FTH.d_date_end
ORDER BY
FTH.link
LIMIT 1
) AS FTH
ON TRUE
LEFT JOIN dbo.ed_registr_pts_cap AS RCap
ON RCap.f_registr_pts = RP.link
AND RCap.b_contract = FALSE
AND COALESCE(_D_Date, NOW()) BETWEEN RCap.d_date AND RCap.d_date_end
LEFT JOIN LATERAL
(
SELECT
RCon_.n_cons,
RCon_.n_cons2,
RCon_.d_date
FROM dbo.ed_registr_pts_cons AS RCon_
WHERE RP.link = RCon_.f_registr_pts
AND RCon_.b_contract = FALSE
AND COALESCE(_D_Date, NOW()) BETWEEN RCon_.d_date AND RCon_.d_date_end
ORDER BY
RCon_.d_date
LIMIT 1
) AS RCon
ON TRUE
LEFT JOIN dbo.ed_registr_pts_calc_methods AS RCM
ON RCM.f_registr_pts = RP.link
AND COALESCE(_D_Date, NOW()) BETWEEN RCM.d_date AND RCM.d_date_end
LEFT JOIN dbo.es_calc_methods AS ECM
ON ECM.link = RCM.f_calc_methods
LEFT JOIN dbo.es_calc_methods AS ECM2
ON ECM2.link = RCM.f_calc_methods_default
LEFT JOIN LATERAL
(
SELECT
EDP1.link,
EDP1.f_devices,
EDP1.f_energy_types,
EDP1.n_percent,
EDP1.n_percent2,
EDP1.b_main,
EDP1.f_division
FROM dbo.ed_devices_pts EDP1
INNER JOIN dbo.ed_devices D1
ON D1.link = EDP1.f_devices
AND D1.d_setup_date <= COALESCE(_D_Date, NOW())
WHERE EDP1.f_registr_pts = RP.link
ORDER BY
D1.d_setup_date DESC
LIMIT 1
) AS EDP
ON TRUE
LEFT JOIN dbo.ed_devices D
ON D.link = EDP.f_devices
LEFT JOIN dbo.es_device_types EDT
ON EDT.link = D.f_device_types
LEFT JOIN dbo.es_device_categories EDC
ON EDC.link = EDT.f_device_categories
LEFT JOIN LATERAL dbo.ef_device_digits_list(D.link) AS Dig
ON TRUE
LEFT JOIN dbo.fs_sale_items AS FSI
ON FSI.link = RP.f_sale_items
LEFT JOIN dbo.fs_sale_categories AS FSC
ON FSC.link = RP.f_sale_category
LEFT JOIN dbo.es_energy_levels AS EEL
ON EEL.link = RP.f_energy_levels
LEFT JOIN dbo.es_balance_types AS EBT
ON EBT.link = RP.f_balance_types
LEFT JOIN dbo.es_loss_algorithms AS ELA
ON ELA.link = RP.f_transf_algorithms
LEFT JOIN dbo.es_loss_algorithms AS ELA2
ON ELA2.link = RP.f_line_algorithms
LEFT JOIN dbo.es_loss_algorithms AS ELA3
ON ELA3.link = RP.f_non_heat_algorithms
LEFT JOIN dbo.fs_norms FN
ON FN.link = RPT.f_norms
LEFT JOIN dbo.es_transf_types AS ETT
ON ETT.link = RP.f_transf_types
LEFT JOIN dbo.es_work_modes AS ESWM
ON ESWM.link = RCap.f_work_modes
LEFT JOIN dbo.es_energy_types AS EET
ON EET.link = EDP.f_energy_types
WHERE RP.d_date_begin <= COALESCE(_D_Date, NOW())
AND RP.f_division = COALESCE(_F_Division, RP.f_division)
AND (
_F_Areas = -1
OR _F_Areas = erpa.f_areas
OR (
_F_Areas IS NULL
AND erpa.f_areas IS NULL
)
OR (
_F_Areas IS NULL
AND erpa.f_areas = 0
)
);
END;
$$;
Initially, I thought the problem was in the tables used, because the structure has changed, but I checked the function with the replacement with the necessary ones, nothing has changed. So I think the problem is not in the tables.
I am using the following query in PostgreSQL:
SELECT
pegawai_nama,
COUNT(operasi_operator_dokter) AS total,
CASE tindakan_golongan WHEN 'KECIL' THEN SUM(tariftindakan_biaya_alkes)
ELSE 0
END AS KECIL,
CASE tindakan_golongan WHEN 'BESAR' THEN SUM(tariftindakan_biaya_alkes)
ELSE 0
END AS BESAR,
CASE tindakan_golongan WHEN 'KHUSUS' THEN SUM(tariftindakan_biaya_alkes
ELSE 0
END AS SEDANG
FROM
t_operasi
LEFT JOIN m_pasien On t_operasi.operasi_pasien_norm = m_pasien.pasien_norm
LEFT JOIN t_pendaftaran on t_operasi.operasi_pendaftaran_id = t_pendaftaran.pendaftaran_id
LEFT JOIN m_tindakan ON t_operasi.operasi_tindakan_id = m_tindakan.tindakan_id
LEFT JOIN m_tarif_tindakan ON m_tindakan.tindakan_id = m_tarif_tindakan.m_tindakan_id
LEFT JOIN m_pegawai ON cast(m_pegawai.pegawai_id as varchar(10)) = t_operasi.operasi_operator_dokter
LEFT JOIN t_diagnosa_pasien ON t_diagnosa_pasien.t_pendaftaran_id = t_pendaftaran.pendaftaran_id
LEFT JOIN m_icd ON m_icd.icd_id = t_diagnosa_pasien.m_icd_id
WHERE operasi_id IS NOT NULL AND tindakan_golongan IN ('KECIL', 'BESAR', 'KHUSUS', 'SEDANG', '')
GROUP BY pegawai_nama, tindakan_golongan;
However, the result below is not what I am after:
Instead I would like the following result:
pegawai_nama total kecil besar sedang khusus
DR. JOKO TRIYONO, SPM 2 189000 0 909700 0
DR. DJOHAR ANWAR 3 567000 0 0 0
Just have this as a nested query, and group it again:
select pegawai_nama, sum(total) as total , sum(kecil) as kecil, sum(besar) as besar, sum(sedang) as sedang
from (
-- insert your query here
) sub
group by pegawai_nama
Try taking out the "tindakan_golongan" column from the GROUP BY.
This is my new code (based on Georgi Raychev's answer):
SELECT
sub.pegawai_nama,
sum(sub.total) as total,
sum(sub.kecil) as kecil,
sum(sub.besar) as besar,
sum(sub.sedang) as sedang,
sum(sub.khusus) as khusus
FROM (
SELECT
pegawai_nama,
COUNT(operasi_operator_dokter) AS total,
CASE tindakan_golongan WHEN 'KECIL' THEN SUM(tariftindakan_biaya_alkes +
tariftindakan_biaya_cover +tariftindakan_biaya)
ELSE 0
END AS kecil,
CASE tindakan_golongan WHEN 'BESAR' THEN SUM(tariftindakan_biaya_alkes +
tariftindakan_biaya_cover +tariftindakan_biaya)
ELSE 0
END AS besar,
CASE tindakan_golongan WHEN 'KHUSUS' THEN SUM(tariftindakan_biaya_alkes +
tariftindakan_biaya_cover +tariftindakan_biaya)
ELSE 0
END AS khusus,
CASE tindakan_golongan WHEN 'SEDANG' THEN SUM(tariftindakan_biaya_alkes +
tariftindakan_biaya_cover +tariftindakan_biaya)
ELSE 0
END AS sedang
FROM
t_operasi
LEFT JOIN m_pasien On t_operasi.operasi_pasien_norm = m_pasien.pasien_norm
LEFT JOIN t_pendaftaran on t_operasi.operasi_pendaftaran_id = t_pendaftaran.pendaftaran_id
LEFT JOIN m_tindakan ON t_operasi.operasi_tindakan_id = m_tindakan.tindakan_id
LEFT JOIN m_tarif_tindakan ON m_tindakan.tindakan_id = m_tarif_tindakan.m_tindakan_id
LEFT JOIN m_pegawai ON cast(m_pegawai.pegawai_id as varchar(10)) = t_operasi.operasi_operator_dokter
LEFT JOIN t_diagnosa_pasien ON t_diagnosa_pasien.t_pendaftaran_id = t_pendaftaran.pendaftaran_id
LEFT JOIN m_icd ON m_icd.icd_id = t_diagnosa_pasien.m_icd_id
WHERE operasi_id IS NOT NULL
GROUP BY pegawai_nama, tindakan_golongan
) AS sub
GROUP BY sub.pegawai_nama
;
And this is the result:
New Result
I am looking to fetch records and I have come through a scenario in which i have to include additional where clauses between the select query using inner join.
select stp.sales_person as "Sales_Person",
max(case when stp.jan_month is null then 0 else stp.jan_month end) as "January",
select sum(so.amount_total) from sale_order so inner join res_users ru on ru.id=so.user_id
where date(so.confirmation_date) > '2017-01-01' and date(so.confirmation_date) < '2017-01-30',
max(case when stp.feb_month is null then 0 else stp.feb_month end) as "February",
max(case when stp.march_month is null then 0 else stp.march_month end) as "March",
max(case when stp.dec_month is null then 0 else stp.dec_month end) as "December"
from sales_target_record stp
inner join res_partner rp on rp.name=stp.sales_person inner join res_users ru on ru.partner_id = rp.id inner join crm_team ct on ru.sale_team_id = ct.id
where ct.name = 'Direct Sales' group by stp.sales_person
I have to insert columns like i tried with sum but is not working as its a join query
You have a syntax issue in your query if this is truly SQL Server
select
stp.sales_person as Sales_Person,
max(case
when stp.jan_month is null
then 0
else stp.jan_month
end) as January,
--This needed parenthese since it's a subquery. Though, it's uncorrelated
( select sum(so.amount_total)
from sale_order so
inner join res_users ru on ru.id=so.user_id
where cast(so.confirmation_date as date) > '2017-01-01' and cast(so.confirmation_date as date) < '2017-01-30'
--here you need to add something like stp.someColumn = so.SomeColumn to correlate it to the outer query
) as SomeNewColumnUnCorrelated,
max(case
when stp.feb_month is null
then 0
else stp.feb_month
end) as February,
max(case
when stp.march_month is null
then 0
else stp.march_month
end) as March,
max(case
when stp.dec_month is null
then 0
else stp.dec_month
end) as December
from
sales_target_record stp
inner join
res_partner rp on
rp.name=stp.sales_person
inner join
res_users ru on
ru.partner_id = rp.id
where
ct.name = 'Direct Sales'
group by
stp.sales_person
I'm trying to count the distinct number of ids in a column and this works fine.
COUNT(DISTINCT messages.id) AS link_created
But when I try to count with a conditional, I get a syntax error, what's the proper syntax to add a case when or some other condition to only count the distinct message ids where the messages.link_label is present?
COUNT(DISTINCT messages.id CASE WHEN messages.link_label IS NOT NULL 1 END) AS link_created
My full query looks like this.
#customers = Customer.select("customers.*,
COUNT(DISTINCT recipient_lists.id) messages_sent,
COUNT(DISTINCT messages.id CASE WHEN messages.link_label IS NOT NULL 1 END) AS link_created,
COALESCE(SUM(video_activities.video_watched_count),0) AS watched_count,
COALESCE(SUM(video_activities.response_count),0) AS response_count,
COALESCE(SUM(video_activities.email_opened_count),0) AS email_opened_count,
COALESCE(SUM(CASE WHEN video_activities.video_watched_at IS NOT NULL THEN 1 ELSE 0 END),0) AS unique_watches,
COALESCE(SUM(CASE WHEN video_activities.email_opened_at IS NOT NULL THEN 1 ELSE 0 END),0) AS unique_opens,
COALESCE(SUM(CASE WHEN video_activities.response_count > 0 THEN 1 ELSE 0 END),0) AS unique_responses,
customers.updated_at AS last_login,
SUBSTRING( email from POSITION( '#' in email) + 1 for length(email)) AS company")
.joins("LEFT JOIN messages ON customers.id = messages.customer_id
LEFT JOIN recipient_lists ON messages.id = recipient_lists.message_id AND messages.link_label is NULL
LEFT JOIN video_activities ON messages.id = video_activities.message_id")
.group("customers.id")
Try this:
COUNT(DISTINCT CASE
WHEN messages.link_label IS NOT NULL
THEN messages.id
ELSE NULL END)
AS link_created
I have the following SQL query on IBM DB2.
SUM(CASE
WHEN verzijaplaca.vpl_vrsteplacila = 9150 THEN
(select sum(verplaca.vpl_bruto)
from pet320.verzijaplaca as verplaca
)
ELSE 0
END) AS "brutoplacazaure"
The inner select works, but when I include it in CASE when it reports error.
ERROR: An operand of a column function is invalid.
DB2 SQL Error:
SQLCODE=-112, SQLSTATE=42607, SQLERRMC=null, DRIVER=3.57.91
Error
Code: -112
Also If I run only
SUM(CASE
WHEN verzijaplaca.vpl_vrsteplacila = 9150 THEN
(1.0)
ELSE 0
END) AS "brutoplacazaure"
it works
Any suggestions?? It seems that DB 2 doesn't support the inner sql in case when case or smth like that
Thank you
the whole sql query is the following
SELECT
zaposleni.za_koda AS "za_koda",
MAX(enotezpiz.ezp_rsza) AS "ezp_rsza",
MAX(zaposleni.za_polnoime) AS "za_polnoime",
MAX(verzije.ve_datnamena) AS "ve_datnamena",
MAX(verzije.ve_datizp) AS "ve_datizp",
MAX(opp_telefonodgos) AS "opp_telefonodgos",
MAX(pod_krajzaizpise ||', ') AS "pod_krajzaizpise",
MAX(racuni.ra_stracuna) AS "ra_stracuna",
MAX(racuni.ra_modul) AS "ra_modul",
MAX(racuni.ra_sklstev) AS "ra_sklstev",
MAX(verzije.ve_datizp) AS "ve_datizp",
MAX(verzije.ve_naziv) AS "ve_naziv",
SUM(CASE
WHEN vrsteplacila.vp_skupinevrpl in (1,2,3,4,16) and vrsteplacila.vp_udodatkov = 0 THEN verzijaplaca.vpl_eure
ELSE 0
END) AS "mfure",
MAX(dmzaposlenih.dmz_enotezpiz) AS "dmz_enotezpiz",
(select
SUM(olajsave.ozz_znesekolajsave) / 12
from
pet320.olajsavedczaposlenih as olajsave
INNER JOIN
pet320.verzije as verzija1
ON
olajsave.ooz_datumod <= verzija1.ve_datkm AND (olajsave.ooz_datumdo IS NULL OR olajsave.ooz_datumdo >= verzija1.ve_datzm)
INNER JOIN
pet320.zaposleni as zapp
ON
olajsave.ozz_zaposleni = zapp.za_id_za
INNER JOIN
pet320.VERZIJAPLACA as vpl
ON
vpl.vpl_verzije = verzija1.ve_id_ve
AND zapp.za_id_za = vpl.vpl_zaposleni
where
1=1
AND (vpl.vpl_vrsteplacila = 9150 OR vpl.vpl_skupinevrpl = 6)) AS "vz_znesvzddc",
SUM(CASE
WHEN vrsteplacila.vp_skupinevrpl = 3 AND vrsteplacila.vp_udodatkov = 0 THEN verzijaplaca.vpl_eure
WHEN vrsteplacila.vp_skupinevrpl = 4 AND vrsteplacila.vp_udodatkov = 1 THEN verzijaplaca.vpl_eure
ELSE
0
END) AS "bolovalure",
SUM(CASE
WHEN vrsteplacila.vp_skupinevrpl = 4 AND vrsteplacila.vp_udodatkov = 0 THEN verzijaplaca.vpl_eure
ELSE
0
END) AS "izostanekzdelaure",
SUM(CASE
WHEN vrsteplacila.vp_skupinevrpl = 3 THEN verzijaplaca.vpl_bruto
ELSE
0
END) AS "brutoznesekboleznine",
SUM(CASE WHEN vrsteplacila.vp_skupinevrpl = 16 THEN verzijaplaca.vpl_bruto
ELSE
0
END) AS "brutodopolnega",
SUM(CASE WHEN vrsteplacila.vp_skupinevrpl = 16 and vrsteplacila.vp_udodatkov = 0 THEN verzijaplaca.vpl_eure
ELSE
0
END) AS "uredopolenga",
SUM(CASE
WHEN vrsteplacila.vp_skupinevrpl IN (16) THEN (verzijaplaca.vpl_bruto - verzijaplaca.vpl_neto)
ELSE
0
END) AS "prispevkizasocvarnost",
SUM(CASE
WHEN vrsteplacila.vp_skupinevrpl IN (16) THEN verzijaplaca.vpl_akdohod
ELSE
0
END) AS "akdohodnine",
SUM(CASE
WHEN verzijaplaca.vpl_skupinevrpl IN (16) THEN verzijaplaca.vpl_neto - verzijaplaca.vpl_akdohod
ELSE
0
END) AS "netonadomestilo",
SUM(CASE WHEN verzijaplaca.vpl_vrsteplacila = 9150 THEN
(select sum(verplaca.vpl_bruto)
from pet320.verzijaplaca as verplaca
INNER JOIN
pet320.verzije as ver
ON
ver.ve_id_ve = verplaca.vpl_verzije
INNER JOIN
pet320.zaposleni as zapo
ON
zapo.za_id_za = verplaca.vpl_zaposleni
AND ver.ve_id_ve = verplaca.vpl_verzije
where verplaca.vpl_vrsteplacila in (select vp_id_vp from pet320.vrsteplacila where vp_skupinevrpl in (1,2))
and verplaca.vpl_zaposleni = zapo.za_id_za
and verplaca.vpl_verzije = ver.ve_id_ve)
ELSE 0
END) AS "brutoplacazaure"
FROM
pet320.verzijaplaca AS verzijaplaca
INNER JOIN
pet320.vrsteplacila AS vrsteplacila
ON
verzijaplaca.vpl_vrsteplacila = vrsteplacila.vp_id_vp
INNER JOIN
pet320.verzije AS verzije
ON
verzijaplaca.vpl_verzije = verzije.ve_id_ve
INNER JOIN
pet320.zaposleni AS zaposleni
ON
verzijaplaca.vpl_zaposleni = zaposleni.za_id_za
INNER JOIN
(SELECT
a.*
FROM
pet320.dmzaposlenih AS a
INNER JOIN
(SELECT
dmz_zaposleni,
MAX(dmz_datumod) AS max_dmz_datumod
FROM
pet320.dmzaposlenih
GROUP BY
dmz_zaposleni) AS b
ON
a.dmz_zaposleni = b.dmz_zaposleni
AND a.dmz_datumod = b.max_dmz_datumod) as dmzaposlenih
ON
dmzaposlenih.dmz_zaposleni = verzijaplaca.vpl_zaposleni
INNER JOIN
pet320.enotezpiz AS enotezpiz
ON
dmzaposlenih.dmz_enotezpiz = enotezpiz.ezp_id_ezp
LEFT JOIN
pet320.osnovnipodplace AS osnovnipodplace
ON
1=1
INNER JOIN
pet320.racuni AS racuni
ON
osnovnipodplace.opp_racuni = racuni.ra_id_ra
INNER JOIN
pet320.podjetja AS podjetja
ON
osnovnipodplace.opp_podjetja = podjetja.pod_id_pod
LEFT JOIN
pet320.verzijazaposleni AS verzijazaposleni
ON
verzijazaposleni.vz_zaposleni = zaposleni.za_id_za
AND verzijazaposleni.vz_verzije = verzije.ve_id_ve
INNER JOIN
pet320.verzijastrmesta as verzijastrmesta
ON
verzijastrmesta.vs_verzije = verzije.ve_id_ve
AND verzijastrmesta.vs_strmesta = dmzaposlenih.dmz_strmesta
INNER JOIN
pet320.verzijaorgenote AS verzijaorgenote
ON
verzijaorgenote.vo_verzije = verzije.ve_id_ve
AND verzijaorgenote.vo_orgenote = dmzaposlenih.dmz_orgenote
INNER JOIN
pet320.zaposinvalidi AS zaposinvalidi
ON
zaposinvalidi.zi_zaposleni = verzijaplaca.vpl_zaposleni and zi_datdo is null
INNER JOIN
pet320.verzijasumstavki AS verzijasumstavki
ON
verzijasumstavki.vss_verzije = verzijaplaca.vpl_verzije AND
verzijasumstavki.vss_zaposleni = verzijaplaca.vpl_zaposleni AND
verzijasumstavki.vss_vrsteplacila = 9301
WHERE
1=1
AND vrsteplacila.vp_skupinevrpl in (1,2,3,4,16)
AND (verzijaplaca.vpl_verzije = 215)
AND (verzijaplaca.vpl_zaposleni IS NULL OR 1=1)
AND (verzijaplaca.vpl_strm_strmesta IS NULL OR 1=1)
AND (dmzaposlenih.dmz_orgenote IS NULL OR 1=1)
AND (dmzaposlenih.dmz_izplacilnamesta IS NULL OR 1=1)
AND (verzijaplaca.vpl_placilnirazredi IS NULL OR 1=1)
AND (dmzaposlenih.dmz_vrstapog IN (1,0))
AND verzijaplaca.vpl_zaposleni in (select distinct vpl_zaposleni from pet320.verzijaplaca where vpl_skupinevrpl = 16 AND vpl_verzije = 215)
group by dmzaposlenih.dmz_enotezpiz,
zaposleni.za_koda
ORDER BY
dmzaposlenih.dmz_enotezpiz,
zaposleni.za_koda
INNER JOIN
(SELECT
a.*
FROM
pet320.dmzaposlenih AS a
INNER JOIN
(SELECT
dmz_zaposleni,
MAX(dmz_datumod) AS max_dmz_datumod
FROM
pet320.dmzaposlenih
GROUP BY
dmz_zaposleni) AS b
ON
a.dmz_zaposleni = b.dmz_zaposleni
AND a.dmz_datumod = b.max_dmz_datumod) as dmzaposlenih
ON
dmzaposlenih.dmz_zaposleni = verzijaplaca.vpl_zaposleni
INNER JOIN
pet320.enotezpiz AS enotezpiz
ON
dmzaposlenih.dmz_enotezpiz = enotezpiz.ezp_id_ezp
LEFT JOIN
pet320.osnovnipodplace AS osnovnipodplace
ON
1=1
INNER JOIN
pet320.racuni AS racuni
ON
osnovnipodplace.opp_racuni = racuni.ra_id_ra
INNER JOIN
pet320.podjetja AS podjetja
ON
osnovnipodplace.opp_podjetja = podjetja.pod_id_pod
LEFT JOIN
pet320.verzijazaposleni AS verzijazaposleni
ON
verzijazaposleni.vz_zaposleni = zaposleni.za_id_za
AND verzijazaposleni.vz_verzije = verzije.ve_id_ve
INNER JOIN
pet320.verzijastrmesta as verzijastrmesta
ON
verzijastrmesta.vs_verzije = verzije.ve_id_ve
AND verzijastrmesta.vs_strmesta = dmzaposlenih.dmz_strmesta
INNER JOIN
pet320.verzijaorgenote AS verzijaorgenote
ON
verzijaorgenote.vo_verzije = verzije.ve_id_ve
AND verzijaorgenote.vo_orgenote = dmzaposlenih.dmz_orgenote
INNER JOIN
pet320.zaposinvalidi AS zaposinvalidi
ON
zaposinvalidi.zi_zaposleni = verzijaplaca.vpl_zaposleni and zi_datdo is null
INNER JOIN
pet320.verzijasumstavki AS verzijasumstavki
ON
verzijasumstavki.vss_verzije = verzijaplaca.vpl_verzije AND
verzijasumstavki.vss_zaposleni = verzijaplaca.vpl_zaposleni AND
verzijasumstavki.vss_vrsteplacila = 9301
WHERE
1=1
AND vrsteplacila.vp_skupinevrpl in (1,2,3,4,16)
AND (verzijaplaca.vpl_verzije = 215)
AND (verzijaplaca.vpl_zaposleni IS NULL OR 1=1)
AND (verzijaplaca.vpl_strm_strmesta IS NULL OR 1=1)
AND (dmzaposlenih.dmz_orgenote IS NULL OR 1=1)
AND (dmzaposlenih.dmz_izplacilnamesta IS NULL OR 1=1)
AND (verzijaplaca.vpl_placilnirazredi IS NULL OR 1=1)
AND (dmzaposlenih.dmz_vrstapog IN (1,0))
AND verzijaplaca.vpl_zaposleni in (select distinct vpl_zaposleni from pet320.verzijaplaca where vpl_skupinevrpl = 16 AND vpl_verzije = 215)
group by dmzaposlenih.dmz_enotezpiz,
zaposleni.za_koda
ORDER BY
dmzaposlenih.dmz_enotezpiz,
zaposleni.za_koda
The query as you tried to write it would run
select sum(verplaca.vpl_bruto)
from pet320.verzijaplaca as verplaca
and produce the exact same result every time the case statement was true. Even if you can do it that way, you shouldn't, because it's a huge waste of time to run that query over and over. Instead, run that statement once and store the value. Then refer to the stored value whenever you need it. Here are a couple of options:
with vpl_bruto_sum as (
select sum(verplaca.vpl_bruto) as total
from pet320.verzijaplaca as verplaca
)
select sum(case when verzijaplaca.vpl_vrsteplacila = 9150
then vpl_bruto_sum.total else 0
end
)
from pet320.verzijaplaca
inner join vpl_bruto_sum on 1=1;
Or you could make thinks simpler by using the join condition instead of the inner case statement:
with vpl_bruto_sum as (
select sum(verplaca.vpl_bruto) as total
from pet320.verzijaplaca as verplaca
)
select sum(vpl_bruto_sum.total)
from pet320.verzijaplaca
left outer join vpl_bruto_sum on verzijaplaca.vpl_vrsteplacila = 9150;
If you want to calculate a value, then use it in multiple different queries, you could use a variable:
create or replace variable my_sum integer;
set my_sum = (select sum(vpl_bruto) from pet320.verzijaplaca);
select sum(case when verzijaplaca.vpl_vrsteplacila = 9150
then my_sum else 0
end
)
from pet320.verzijaplaca;
Hopefully that will help you get started.
It looks like there are probably other problems with your query as well. For example, where 1=1 and... is not a useful construct. It might be worth seeking help about how to design a better query--I think it could be a lot simpler, though it's hard to say without knowing what you are doing.