PostgreSQL code optimalization - sql

I have this code:
SELECT
rv_storage.m_product_id AS n_product_id,
rv_storage.value,
rv_storage.name,
m_warehouse.name AS warehouse_name,
rv_storage.qtyonhand,
rv_transaction.m_transaction_id,
CASE WHEN rv_transaction.movementtype = 'V+' THEN movementdate
ELSE NULL END AS last_in,
CASE WHEN rv_transaction.movementtype = 'C-' THEN movementdate
ELSE NULL END AS last_out,
rv_transaction.movementagedays,
CASE WHEN (movementagedays < -90) AND (movementagedays >= -180) THEN qtyonhand
ELSE NULL END AS more_than_90,
CASE WHEN movementagedays < -180 THEN qtyonhand
ELSE NULL END AS more_than_180
FROM
adempiere.rv_storage
INNER JOIN
adempiere.rv_transaction ON
rv_transaction.m_product_id = rv_storage.m_product_id
AND rv_transaction.movementagedays = (
SELECT MAX(movementagedays)
FROM adempiere.rv_transaction
WHERE
rv_transaction.m_product_id = rv_storage.m_product_id
AND rv_transaction.movementtype = 'C-'
OR rv_transaction.movementtype = 'V+'
)
INNER JOIN
adempiere.m_warehouse ON
m_warehouse.m_warehouse_id = rv_storage.m_warehouse_id
WHERE rv_storage.m_product_id IN (
SELECT m_product_id
FROM adempiere.rv_transaction
WHERE movementagedays < -90
)
ORDER BY n_product_id;
That results in following table:
table http://img9.imageshack.us/img9/4506/table3n.png
But on the server with live data (100k+ rows on each table ) it is too slow.
Can somebody tell me how can the code be optimized?
Thank You

The subquery in the where clause is redundant. And I think you are missing a parenthesis in the where clause of the subquery in the inner join:
SELECT
rv_storage.m_product_id AS n_product_id,
rv_storage.value,
rv_storage.name,
m_warehouse.name AS warehouse_name,
rv_storage.qtyonhand,
rv_transaction.m_transaction_id,
CASE WHEN rv_transaction.movementtype = 'V+' THEN movementdate
ELSE NULL END AS last_in,
CASE WHEN rv_transaction.movementtype = 'C-' THEN movementdate
ELSE NULL END AS last_out,
rv_transaction.movementagedays,
CASE WHEN (movementagedays < -90) AND (movementagedays >= -180) THEN qtyonhand
ELSE NULL END AS more_than_90,
CASE WHEN movementagedays < -180 THEN qtyonhand
ELSE NULL END AS more_than_180
FROM
adempiere.rv_storage
INNER JOIN
adempiere.rv_transaction ON
rv_transaction.m_product_id = rv_storage.m_product_id
AND rv_transaction.movementagedays = (
SELECT MAX(movementagedays)
FROM adempiere.rv_transaction
WHERE
rv_transaction.m_product_id = rv_storage.m_product_id
AND (rv_transaction.movementtype = 'C-'
OR rv_transaction.movementtype = 'V+')
)
INNER JOIN
adempiere.m_warehouse ON
m_warehouse.m_warehouse_id = rv_storage.m_warehouse_id
WHERE movementagedays < -90
ORDER BY n_product_id;
Now post the explain output.

IN() and NOT IN() subqueries are poorly optimized:
MySQL executes the subquery as a dependent subquery for each row in the outer query. This is a frequent cause of serious performance problems in MySQL 5.5 and older versions. The query probably should be rewritten as a JOIN or a LEFT OUTER JOIN, respectively.

Related

Combine 3 big tables with 2 joins

I have three tables using complex. I run them separately without problems. Here are the queries:
TABLE A:
select
maxxx.id_demande_diffusion AS ID_DIFFUSION,
maxxx.id_notification as ID_NOTIFICATION,
maxxx.cd_organisation_client as ID_ENTITE,
maxxx.cod_entrep as ID_ENTITE_GARANTE,
maxxx.cd_canal as CD_CANAL,
maxxx.id_demande_diffusion_originale as ID_DIFFUSION_PARENT,
maxxx.ref_maquette as REF_MAQUETTE,
maxxx.qualification_canal as QUALIFICATION_CANAL,
maxxx.ger_id_pli as ID_PLI_GER,
case when maxxx.typ_mvt="S" then 1 else 0 end AS TOP_SUPP,
case when maxxx.typ_mvt = "S" then to_date(substr(maxxx.dt_capt, 1, 11)) else null end AS DT_SUPP,
minnn.typ_mvt as MIN_MVT,
maxxx.typ_mvt as MAX_MVT,
case when minnn.typ_mvt = 'C' then 'C' else 'M' end as TYP_MVT
from
(select s.id_demande_diffusion, s.dt_capt, s.typ_mvt from ${use_database}.pz_send_demande_diffusion as s
join
(select id_demande_diffusion, min(dt_capt) as dtmin from ${use_database}.pz_send_demande_diffusion group by id_demande_diffusion) as minn
on minn.id_demande_diffusion=s.id_demande_diffusion and s.dt_capt=minn.dtmin ) as minnn
join
(select s.id_demande_diffusion, s.typ_mvt, s.id_notification, s.dt_capt, s.cd_organisation_client, s.cod_entrep, s.cd_canal, s.id_demande_diffusion_originale,
s.ref_maquette, s.qualification_canal, s.ger_id_pli from ${use_database}.pz_send_demande_diffusion as s
join
(select id_demande_diffusion, max(dt_capt) as dtmax from ${use_database}.pz_send_demande_diffusion group by id_demande_diffusion) as maxx
on s.id_demande_diffusion=maxx.id_demande_diffusion and s.dt_capt=maxx.dtmax)as maxxx
on minnn.id_demande_diffusion=maxxx.id_demande_diffusion;
TABLE B:
select
maxxx.id_notification as ID_NOTIFICATION,
maxxx.cd_type_destinataire as CD_TYPE_DESTINATAIRE,
case when maxxx.cd_type_destinataire = "IDGRC" then maxxx.destinataire else null end AS ID_PERSONNE,
case when maxxx.cd_type_destinataire = "MAIL" then maxxx.destinataire else null end AS EMAIL_DESTINATAIRE,
case when maxxx.cd_type_destinataire = "SMS" then maxxx.destinataire else null end AS NUM_TEL_DESTINATAIRE,
maxxx.cd_type_evenement,
maxxx.cd_type_notification,
maxxx.cd_type_destinataire_source AS CD_TYPE_DEST_SOURCE,
case when maxxx.cd_type_destinataire_source = "IDGRC" then maxxx.destinataire_source when maxxx.cd_type_destinataire_source = "IDGRC|IDGRC" then substr(maxxx.destinataire_source, 1, locate("|", maxxx.destinataire_source)-1) else null end AS ID_PERS_DEST_SOURCE,
case when maxxx.cd_type_destinataire_source = "SIGMA" or maxxx.cd_type_destinataire_source = "CUBA" then maxxx.destinataire_source else null end AS REF_EXT_DEST_SOURCE,
case when maxxx.cd_type_destinataire_source = "MAIL" then maxxx.destinataire_source else null end AS EMAIL_DEST_SOURCE,
case when maxxx.cd_type_destinataire_source = "SMS" then maxxx.destinataire_source else null end AS NUM_TEL_DEST_SOURCE,
case when maxxx.cd_type_destinataire_source = "IDGRC|IDGRC" then substr(maxxx.destinataire_source, locate("|", maxxx.destinataire_source)+1, length(maxxx.destinataire_source)) end AS ID_PERSONNE_DEST_SOURCE_2
from
(select n.id_notification, n.destinataire, n.cd_type_evenement, n.cd_type_notification, n.destinataire_source, n.cd_type_destinataire, n.cd_type_destinataire_source from ${use_database}.pz_send_notification as n
join
(select id_notification, max(dt_capt) as dtmax from ${use_database}.pz_send_notification group by id_notification) as maxx
on n.id_notification=maxx.id_notification and n.dt_capt=maxx.dtmax) as maxxx;
TABLE C:
select
maxxx.id_communication AS ID_COMMUNICATION,
maxxx.cd_sa as CD_SYS_DIFFUSEUR,
maxxx.type_conteneur as CD_TYPE_CONTENEUR
from
(select n.id_communication, n.cd_sa, n.type_conteneur from ${use_database}.pz_send_comm_retour as n
join
(select id_communication, max(dt_capt) as dtmax from ${use_database}.pz_send_comm_retour group by id_communication) as maxx
on n.id_communication=maxx.id_communication and n.dt_capt=maxx.dtmax) as maxxx;
Is there anyway to combine the three of the using one join and one left join ?
I want o have something like
SELECT * FROM (TABLE A join TABLE B ON A.ID_NOTIFICATION=B.ID_NOTIFICATION) AS TMP LEFT JOIN TABLE C ON TMP.ID_DIFFUSION=C.ID_COMMUNICATION;
I have been trying but it always fails because of missing or misplaced parenthesis.
Thank you!
I have no idea if your queries are correct, but common table expressions (CTE) can frequently be used to keep result set joins clean.
WITH TABLE_A AS
( SELECT
FROM ...
...
),
TABLE_B AS
( SELECT
FROM ...
...
),
TABLE_C AS
( SELECT
FROM ...
...
)
SELECT *
FROM TABLE_A TA
JOIN TABLE_B TB
ON TA.Key_Field = TB.Key_Field
JOIN TABLE_C TC
ON TB.Key_Field = TC.Key_Field

Can i use case expressions on both sides of the where clause?

Like this
SELECT *
FROM UsersMedicalSurgicalHistory UMSH INNER JOIN CCDTransaction CT on
UMSH.SurgicalHistoryId = CT.RowId
WHERE (
(CASE
WHEN LEN(UMSH.DateOfProcedure)<=4 THEN UMSH.DateOfProcedure
WHEN LEN(UMSH.DateOfProcedure)=0 THEN UMSH.DateOfProcedure
END
=
CASE WHEN #CodeFilter3 IS not null THEN #CodeFilter3
ELSE UMSH.DateOfProcedure end)
OR
(CASE
WHEN LEN(UMSH.DateOfProcedure)>4 THEN
CONVERT(datetime,UMSH.DateOfProcedure,101)
ELSE GETDATE()
END
=
CASE WHEN #CodeFilter2 IS not null THEN #CodeFilter2
ELSE GETDATE()
END)
)
So the question is like CASE expression can be used on both side of WHERE clause
As per your query is written above...
CASES can be minimized to nested conditions as,
SELECT * FROM UsersMedicalSurgicalHistory UMSH
INNER JOIN CCDTransaction CT on UMSH.SurgicalHistoryId = CT.RowId
WHERE (
(UMSH.DateOfProcedure = #CodeFilter3 and #CodeFilter3 IS not null)
OR
#CodeFilter3 IS null
)
OR
(
(
(LEN(UMSH.DateOfProcedure)>4 AND CONVERT(datetime,UMSH.DateOfProcedure,101)=#CodeFilter2)
OR
(LEN(UMSH.DateOfProcedure)<=4 AND GETDATE() =#CodeFilter2)
AND #CodeFilter2 IS NOT NULL
)
OR
(LEN(UMSH.DateOfProcedure)<=4 AND #CodeFilter2 IS null)
)
Try this query... hope it gives desired output :)

errors when using case in where clause

I have used following code.. but it have some erors...pls help me
SELECT VoucherTypes.types,
VoucherHead.VoucherNo,
VoucherHead.VoucherDate,
SUM(VoucherDetail.Debit) AS debit,
SUM(VoucherDetail.Credit) AS credit,
VoucherHead.VoucherStatus
FROM VoucherHead
INNER JOIN VoucherTypes
ON VoucherHead.VoucherType = VoucherTypes.vtypeid
INNER JOIN VoucherDetail
ON VoucherHead.VoucherID = VoucherDetail.VoucherID
WHERE(VoucherHead.VoucherDate >= #fromdate)
AND (VoucherHead.VoucherDate <= #todate)
AND (VoucherTypes.types = #vtype)
AND (VoucherHead.Branchno = #branchid)
and case(VoucherHead.VoucherStatus)
when #val=1 then
VoucherHead.VoucherStatus='true'
when #val=2 then
VoucherHead.VoucherStatus=false
when #val=0 then
VoucherHead.VoucherStatus=true or
VoucherHead.VoucherStatus=false or
VoucherHead.VoucherStatus is null
GROUP BY VoucherTypes.types,
VoucherHead.VoucherNo,
VoucherHead.VoucherDate,
VoucherHead.VoucherStatus
Try this, might work for you. Itis tough to understand your Requirement through your Question.
SELECT VoucherTypes.types,
VoucherHead.VoucherNo,
VoucherHead.VoucherDate,
SUM(VoucherDetail.Debit) AS debit,
SUM(VoucherDetail.Credit) AS credit,
VoucherHead.VoucherStatus
FROM VoucherHead
INNER JOIN VoucherTypes ON VoucherHead.VoucherType = VoucherTypes.vtypeid
INNER JOIN VoucherDetail ON VoucherHead.VoucherID = VoucherDetail.VoucherID
WHERE (VoucherHead.VoucherDate >= #fromdate)
AND (VoucherHead.VoucherDate <= #todate)
AND (VoucherTypes.types = #vtype)
AND (VoucherHead.Branchno = #branchid)
AND (#val=0 OR VH.VoucherStatus = case when #val=1 then 'true'
when #val=2 then 'false' END)
GROUP BY VoucherTypes.types, VoucherHead.VoucherNo, VoucherHead.VoucherDate, VoucherHead.VoucherStatus
You should write a query as:
SELECT VT.[types],
VH.VoucherNo,
VH.VoucherDate,
SUM(VD.Debit) AS debit,
SUM(VD.Credit) AS credit,
VH.VoucherStatus
FROM VoucherHead VH
INNER JOIN VoucherTypes VT ON VH.VoucherType = VT.vtypeid
INNER JOIN VoucherDetail VD ON VH.VoucherID = VD.VoucherID
WHERE (VH.VoucherDate >= #fromdate)
AND (VH.VoucherDate <= #todate)
AND (VT.[types] = #vtype)
AND (VH.Branchno = #branchid)
and 1 = ( CASE
when #val=1 AND VH.VoucherStatus='true' THEN 1
when #val=2 AND VH.VoucherStatus='false' THEN 1
--when #val= 0 AND (VH.VoucherStatus='true' or
--VH.VoucherStatus='false' or VH.VoucherStatus is NULL)
--THEN 1
when #val=3 THEN 1 ELSE 0 END )
GROUP BY VT.[types], VH.VoucherNo, VH.VoucherDate, VH.VoucherStatus
The regular CASE syntax is (somewhat simplified):
case when x = y then value-expression1
when z = q then value-expression2
etc...
[ else value-expressionx ]
end
The else-clause is optional. All return value-expressions must have compatible data-types.

Error cannot generate SQL for Custom SQL at BO

I'm using business object 4 and currently developing a report using custom SQL. Total object and data type selected using custom sql and object at webbi already the same. But when I try to validate webbi always sends error cannot generate sql.
How to fix this and what is the cause of this error?
My sql syntax is as follows:
select * from(
SELECT
DISTINCT
CASE WHEN TRIM(msv26A.PROJECT_NO) IS NULL THEN msvPRJ.PROJECT_NO ELSE msv26A.PROJECT_NO END,
msv660.PROJ_DESC,
msv26A.PO_NO,
msv200.SUPPLIER_NAME,
msv26A.SUPPLIER_NO,
msv260.EXT_INV_NO,
msv200.SUP_TYPEX1,
msv260.CURRENCY_TYPE,
msv000_DC0001.DSTRCT_CODE,
msv000_DC0001.DSTRCT_NAME,
msv260.PMT_STATUS,
msv260.DUE_DATE,
msv260.INV_DATE,
msv260.FOR_INV_ORIG,
msv260.LOC_INV_ORIG,
msv260.FOR_INV_AMD,
msv260.LOC_INV_AMD,
msv260.AMT_RETAINED,
msv260.PRESC_PMT_AMT,
msv260.PP_AMT_LOC,
msv260_1.AMT_PAID_FOR,
msv071.REF_CODE,
CASE WHEN EMV260_AGING_RETENTION.LOC_INV_RETENTION IS NULL THEN 0 ELSE EMV260_AGING_RETENTION.LOC_INV_RETENTION END,
CASE WHEN EMV260_AGING_RETENTION.FOR_INV_RETENTION IS NULL THEN 0 ELSE EMV260_AGING_RETENTION.FOR_INV_RETENTION END
FROM
msv200 RIGHT OUTER JOIN msv26A ON (msv26A.SUPPLIER_NO = msv200.SUPPLIER_NO)
INNER JOIN msv000_DC0001 ON (msv000_DC0001.DSTRCT_CODE = msv26A.DSTRCT_CODE)
INNER JOIN msv260 ON (msv26A.DSTRCT_CODE = msv260.DSTRCT_CODE AND msv26A.SUPPLIER_NO = msv260.SUPPLIER_NO AND msv26A.INV_NO = msv260.INV_NO)
LEFT OUTER JOIN msvPRJ ON (msvPRJ.DSTRCT_CODE = msv26A.DSTRCT_CODE AND TRIM(msvPRJ.PO_NO) = trim(msv26A.PO_NO))
LEFT OUTER JOIN msv660 ON (msv26A.DSTRCT_CODE = msv660.DSTRCT_CODE AND (CASE WHEN TRIM(msv26A.PROJECT_NO) IS NULL
THEN msvPRJ.PROJECT_NO ELSE msv26A.PROJECT_NO END) = msv660.PROJECT_NO)
LEFT OUTER JOIN msv260 msv260_1 ON (msv260_1.DSTRCT_CODE = msv260.DSTRCT_CODE and msv260_1.SUPPLIER_NO = msv260.SUPPLIER_NO and msv260_1.INV_NO = msv260.INV_NO)
LEFT OUTER JOIN msv071 ON (msv071.ENTITY_VALUE=msv260.SUPPLIER_NO AND msv071.ENTITY_TYPE='SUP')
LEFT OUTER JOIN (SELECT A.DSTRCT_CODE,
A.SUPPLIER_NO,
A.ORIG_INV_NO,
SUM(CASE WHEN A.LOC_INV_AMD <> 0
THEN A.LOC_INV_AMD ELSE A.LOC_INV_ORIG END) LOC_INV_RETENTION,
SUM(CASE WHEN A.FOR_INV_AMD <> 0
THEN A.FOR_INV_AMD ELSE A.FOR_INV_ORIG END) FOR_INV_RETENTION
FROM msv260 A
WHERE A.FULL_PER_LOADED <= #prompt('Enter Full Period(From):','A','260\Full Per Loaded',Mono,Free,Persistent,,User :3)
AND TRIM(A.PMT_STATUS) >= '30' AND TRIM(A.PMT_STATUS) <= '55'
GROUP BY
A.DSTRCT_CODE,
A.SUPPLIER_NO,
A.ORIG_INV_NO) EMV260_AGING_RETENTION
ON (msv260.DSTRCT_CODE = EMV260_AGING_RETENTION.DSTRCT_CODE
AND msv260.SUPPLIER_NO = EMV260_AGING_RETENTION.SUPPLIER_NO
AND msv260.INV_NO = EMV260_AGING_RETENTION.ORIG_INV_NO)
WHERE
msv26A.DSTRCT_CODE in #prompt('Enter value(s) for Dstrct Code:','A','msv26a\Dstrct Code',Multi,Free,Persistent,,User:5)
AND
TRIM(msv260.PMT_STATUS) >= '30' AND TRIM(msv260.PMT_STATUS) <= '55'
AND
(
( msv260.FULL_PER_LOADED <= #prompt('Enter Full Period(From):','A','260\Full Per Loaded',Mono,Free,Persistent,,User :3)
AND msv260.FULL_PER_PAID = '000000' )
OR
( msv260.FULL_PER_PAID > #prompt('Enter Full Period(To):','A','260\Full Per Paid',Mono,Free,Persistent,,User :4)
AND msv260.FULL_PER_LOADED <= #prompt('Enter Full Period(From):','A','260\Full Per Loaded',Mono,Free,Persistent,,User :3) )
)
AND msv260.CURRENCY_TYPE <> ' '
ORDER BY msv000_DC0001.DSTRCT_CODE, msv260.SUPPLIER_NO, msv200.SUP_TYPEX1, msv260.CURRENCY_TYPE)
WHERE (DSTRCT_CODE,SUPPLIER_NO,EXT_INV_NO) IN (SELECT
DISTINCT DSTRCT_CODE,SUPPLIER_NO,EXT_INV_NO FROM msv900
WHERE DSTRCT_CODE in #prompt('Enter value(s) for Dstrct Code:','A','msv900\Dstrct Code',Multi,Free,Persistent,,User:1)
AND FULL_PERIOD <= #prompt('Enter Full Period(From):','A','msv900\Full Period',Mono,Free,Persistent,,User :2)
AND ACCOUNT_CODE IN ('21101')
)
ORDER BY
PROJECT_NO,
SUPPLIER_NO

Excel: Incorrect Syntax near the keyword 'SELECT'

Scenario: I am building a report in Excel to calculate commissions. This is based on Invoices from the previous month.
I created the following tsql query and created a connection using MSQuery. I tested the query and it works perfect until I change my Where statement to use the parameter "?" so I can , then I get the following error:
Incorrect Syntax near the keyword `'SELECT'`
Here is the query:
SELECT v_rpt_Invoices.Invoice_Number, v_rpt_Invoices.Territory, v_rpt_Company.Account_Nbr, v_rpt_Invoices.Company_Name, v_rpt_Invoices.Date_Invoice,
v_rpt_Invoices.Location, v_rpt_Invoices.TicketNbr, v_rpt_Invoices.Project_ID, v_rpt_Invoices.Invoice_Type, v_rpt_Invoices.Status_Description,
CASE WHEN TicketNbr <> 0 THEN 'Service Ticket' WHEN Project_ID IS NOT NULL THEN 'Project' ELSE 'Other' END AS Invoice_For,
CASE WHEN ticketNbr <> 0 THEN
(SELECT v_rpt_Service.Board_Name
FROM v_rpt_Service
WHERE v_rpt_Invoices.TicketNbr = v_rpt_Service.TicketNbr) WHEN Project_ID IS NOT NULL THEN Project_ID ELSE 'Other' END AS Service_Board_Project,
CASE WHEN TicketNbr <> 0 THEN
(SELECT Bill_Method
FROM SR_Service
WHERE v_rpt_Invoices.TicketNbr = SR_Service.SR_Service_RecID) WHEN project_id IS NOT NULL THEN
(SELECT PM_Billing_Method_ID
FROM PM_Project
WHERE v_rpt_Invoices.PM_Project_RecID = PM_Project.PM_Project_RecID) ELSE 'NONE' END AS BillingMethod, v_rpt_Invoices.Invoice_Amount,
CASE WHEN (TicketNbr <> 0 AND
(SELECT Bill_Method
FROM SR_Service
WHERE v_rpt_Invoices.TicketNbr = SR_Service.SR_Service_RecID) = 'A') THEN Invoice_Amount * 0.7 WHEN (TicketNbr <> 0 AND
(SELECT Bill_Method
FROM SR_Service
WHERE v_rpt_Invoices.TicketNbr = SR_Service.SR_Service_RecID) = 'F') THEN 0.01 WHEN (project_id IS NOT NULL AND
(SELECT PM_Billing_Method_ID
FROM PM_Project
WHERE v_rpt_Invoices.PM_Project_RecID = PM_Project.PM_Project_RecID) = 'A') THEN Invoice_Amount * 0.7 WHEN (project_id IS NOT NULL AND
(SELECT PM_Billing_Method_ID
FROM PM_Project
WHERE v_rpt_Invoices.PM_Project_RecID = PM_Project.PM_Project_RecID) = 'F') THEN 0.01 ELSE 0.00 END AS Cost
FROM v_rpt_Invoices INNER JOIN
v_rpt_Company ON v_rpt_Invoices.Company_RecID = v_rpt_Company.Company_RecID
**WHERE (v_rpt_Invoices.Date_Invoice >= ?)**
order by Territory, Invoice_For
Remove this line
**WHERE (v_rpt_Invoices.Date_Invoice >= ?)**
That is not valid SQL -- looks like you want to comment use double dash.
Unless you are just putting the ** to show what you changed. In that case you need to have a value where the ? is the SQL won't work.
As an asside, this query could be made much clearer and faster. Consider consolidating sub-queries into a join. For example, the following sub-query
SELECT Bill_Method
FROM SR_Service
WHERE v_rpt_Invoices.TicketNbr = SR_Service.SR_Service_RecID
MUST be called for every row -- if you make this a join you go from O(nm) to O(n+m) Where n is the size of v_rpt_Invoices and m is the size of SR_Service.
This is just one of the potential sub-queries you can optimize.
Here is an example of rolling in the sub-queries to your example
(I can't test so it might have bugs / typos)
SELECT
v_rpt_Invoices.Invoice_Number,
v_rpt_Invoices.Territory,
v_rpt_Company.Account_Nbr,
v_rpt_Invoices.Company_Name,
v_rpt_Invoices.Date_Invoice,
v_rpt_Invoices.Location,
v_rpt_Invoices.TicketNbr,
v_rpt_Invoices.Project_ID,
v_rpt_Invoices.Invoice_Type,
v_rpt_Invoices.Status_Description,
CASE WHEN TicketNbr <> 0 THEN 'Service Ticket'
WHEN Project_ID IS NOT NULL THEN 'Project'
ELSE 'Other'
END AS Invoice_For,
CASE WHEN ticketNbr <> 0 THEN v_rpt_Service.Board_Name
WHEN Project_ID IS NOT NULL THEN Project_ID
ELSE 'Other'
END AS Service_Board_Project,
CASE WHEN TicketNbr <> 0 THEN SR_Service.Bill_Method
WHEN project_id IS NOT NULL THEN PM_Project.PM_Billing_Method_ID
ELSE 'NONE'
END AS BillingMethod, v_rpt_Invoices.Invoice_Amount,
CASE WHEN (TicketNbr <> 0 AND SR_Service.Bill_Method ='A') THEN Invoice_Amount * 0.7
WHEN (TicketNbr <> 0 AND SR_Service.Bill_Method ='F') THEN 0.01
WHEN (project_id IS NOT NULL AND PM_Project.PM_Billing_Method_ID = 'A') THEN Invoice_Amount * 0.7
WHEN (project_id IS NOT NULL AND PM_Project.PM_Billing_Method_ID = 'F') THEN 0.01
ELSE 0.00
END AS Cost
FROM v_rpt_Invoices
INNER JOIN v_rpt_Company ON v_rpt_Invoices.Company_RecID = v_rpt_Company.Company_RecID
LEFT JOIN SR_Service ON v_rpt_Invoices.TicketNbr = SR_Service.SR_Service_RecID
LEFT JOIN PM_Project ON v_rpt_Invoices.PM_Project_RecID = PM_Project.PM_Project_RecID
LEFT JOIN v_rpt_Service ON v_rpt_Invoices.TicketNbr = v_rpt_Service.TicketNbr
WHERE (v_rpt_Invoices.Date_Invoice >= '1/1/2013')
order by Territory, Invoice_For