I have the following SQL query, and I would need it to run SELECT statement only once.
May I know what are the changes I should make?
EDIT: Need to change to use only one SELECT statement..
DECLARE
#lang varchar(2) ='en',
#hideInactiveCompany integer = 0
IF #hideInactiveCompany = 1
SELECT <all columns>
FROM Config.BusinessUnit BU
LEFT JOIN Config.Organization CO on BU.OrganizationId = CO.OrganizationId
LEFT JOIN Config.ParentBusinessUnit PBU on BU.ParentBusinessUnitId = PBU.ParentBusinessUnitId
WHERE BU.IsActive = 1 --the additional condition if #hideInactiveCompany=1
ORDER BY CASE WHEN #lang = 'cn' THEN BU.Lang END,
CASE WHEN #lang = 'en' THEN BU.Lang END DESC,
EntityName
ELSE
SELECT <all columns>
FROM Config.BusinessUnit BU
LEFT JOIN Config.Organization CO on BU.OrganizationId = CO.OrganizationId
LEFT JOIN Config.ParentBusinessUnit PBU on BU.ParentBusinessUnitId = PBU.ParentBusinessUnitId
ORDER BY CASE WHEN #lang = 'cn' THEN BU.Lang END,
CASE WHEN #lang = 'en' THEN BU.Lang END DESC,
EntityName
If #hideInactiveCompany = 1, display output with BU.IsActive =1
If #hideInactiveCompany = 0, display output without BU.IsActive
filter.
We can try writing the following WHERE clause:
WHERE
(hideInactiveCompany = 1 AND BU.IsActive IS NOT NULL) OR
(hideInactiveCompany IS NULL AND BU.IsActive IS NULL) OR
(hideInactiveCompany <> 1)
Note: The OP has since changed the question a few times after I answered. The latest answer appears to be this:
WHERE
(hideInactiveCompany = 1 AND BU.IsActive = 1) OR
hideInactiveCompany IS NULL OR hideInactiveCompany <> 1
If i do understand your requirement correctly, the entire query should have only one single SELECT clause
DECLARE
#lang varchar(2) ='en',
#hideInactiveCompany integer = 0
SELECT <all columns>
FROM Config.BusinessUnit BU
LEFT JOIN Config.Organization CO on BU.OrganizationId = CO.OrganizationId
LEFT JOIN Config.ParentBusinessUnit PBU on BU.ParentBusinessUnitId = PBU.ParentBusinessUnitId
WHERE (#hideInactiveCompany = 1 AND BU.IsActive = 1)
OR (#hideInactiveCompany <> 1)
ORDER BY CASE WHEN #lang = 'cn' THEN BU.Lang END,
CASE WHEN #lang = 'en' THEN BU.Lang END DESC,
EntityName
Explanation on WHERE
Basically there are only 2 conditions:-
Condition 1 : #hideInactiveCompany = 1 AND BU.IsActive = 1
Condition 2 : #hideInactiveCompany <> 1
Condition 1 is as what you specified. When variable #hideInactiveCompany is 1, IsActive must be 1
Condition 2 is when variable #hideInactiveCompany not equal to 1
You cannot do such a "conditionally build my select" in SQL. You need to write the complete select query twice, one for each branch of the if.
(SQL is generally not a "composable" langauge, you cannot freely combine the elements how you want.)
You might be able to use case and other expressions to rebuild in a single query, or doing the common part of the query into a temporary table (or table valued variable) and then only the final part twice.
Use IF ELSE condition:
ALTER PROCEDURE [Config].[usp_ListBusinessUnit]
#lang VARCHAR(2) = NULL,
#hideInactiveCompany INTEGER
AS
BEGIN
IF #hideInactiveCompany=1
SELECT <all columns>
FROM Config.BusinessUnit BU
LEFT JOIN Config.Organization CO ON BU.OrganizationId = CO.OrganizationId
LEFT JOIN Config.ParentBusinessUnit PBU ON BU.ParentBusinessUnitId =
PBU.ParentBusinessUnitId
WHERE BU.IsActive IS NOT NULL
ORDER BY
CASE WHEN #lang = 'cn' THEN BU.Lang END,
CASE WHEN #lang = 'en' THEN BU.Lang END DESC,
EntityName
ELSE
SELECT <all columns>
FROM Config.BusinessUnit BU
LEFT JOIN Config.Organization CO ON BU.OrganizationId = CO.OrganizationId
LEFT JOIN Config.ParentBusinessUnit PBU ON BU.ParentBusinessUnitId =
PBU.ParentBusinessUnitId
WHERE BU.IsActive IS NULL
ORDER BY
CASE WHEN #lang = 'cn' THEN BU.Lang END,
CASE WHEN #lang = 'en' THEN BU.Lang END DESC,
EntityName
END
Related
I am needing help converting a PostgreSQL query to MSSQ.
Below is what i have done so far but i am issuing with the function and array areas which i do not think are allowed in MS SQL.
Is there something that that i need to do change the function and looks the WHERE statement has an array in it too.
I have added the select statement for the #temp table but when i create the #temp table i am getting errors saying incorrect syntax
CREATE FUNCTION pm_aggregate_report
(
_facility_ids uuid[]
, _risk_ids uuid[] DEFAULT NULL::uuid[]
, _assignee_ids uuid[] DEFAULT NULL::uuid[]
, _start_date date DEFAULT NULL::date
, _end_date date DEFAULT NULL::date
)
RETURNS TABLE
(
facility character varying
, pm_id uuid, grouped_pm boolean
, risk_id uuid
, risk character varying
, pm_status_id uuid
, user_id uuid
, assignee text
, completed_by uuid
, total_labor bigint
)
CREATE TABLE #tmp_pm_aggregate
(
facility_id VARCHAR(126),
pm_id VARCHAR(126),
grouped_pm VARCHAR(126),
risk_id VARCHAR(126),
pm_status_id VARCHAR(126),
user_id VARCHAR(126),
completed_by VARCHAR(126)
)
SELECT DISTINCT
COALESCE(gp.facility_id, a.facility_id) as facility_id,
COALESCE(p.grouped_pm_id, p.id) as pm_id,
CASE WHEN p.grouped_pm_id IS NULL THEN false ELSE true END as grouped_pm,
COALESCE(gp.risk_id, a.risk_id) as risk_id,
COALESCE(gp.pm_status_id, p.pm_status_id) as pm_status_id,
COALESCE(gass.user_id, sass.user_id) as user_id,
COALESCE(gp.completed_by, p.completed_by) as completed_by
FROM pms p
JOIN assets a
ON p.asset_id = a.id
LEFT JOIN grouped_pms gp
ON p.grouped_pm_id = gp.id
LEFT JOIN assignees sass
ON p.id = sass.record_id
AND sass.type = 'single_pm'
LEFT JOIN assignees gass
ON p.grouped_pm_id = gass.record_id
AND gass.type = 'grouped_pm'
LEFT JOIN users u
ON (sass.user_id = u.id OR gass.user_id = u.id)
WHERE a.facility_id = ANY(_facility_ids)
AND NOT a.is_component
AND COALESCE(gp.pm_status_id, p.pm_status_id) in ('f9bdfc17-3bb5-4ec0-8477-24ef05ea3b9b', '06fc910c-3d07-4284-8f6e-8fb3873f5333')
AND COALESCE(gp.completion_date, p.completion_date) BETWEEN COALESCE(_start_date, '1/1/2000') AND COALESCE(_end_date, '1/1/3000')
AND COALESCE(gp.show_date, p.show_date) <= CURRENT_TIMESTAMP
AND COALESCE(gass.user_id, sass.user_id) IS NOT NULL
AND u.user_type_id != 'ec823d98-7023-4908-8006-2e33ddf2c11b'
AND (_risk_ids IS NULL OR COALESCE(gp.risk_id, a.risk_id) = ANY(_risk_ids)
AND (_assignee_ids IS NULL OR COALESCE(gass.user_id, sass.user_id) = ANY(_assignee_ids);
SELECT
f.name as facility,
t.pm_id,
t.grouped_pm,
t.risk_id,
r.name as risk,
t.pm_status_id,
t.user_id,
u.name_last + ', ' + u.name_first as assignee,
t.completed_by,
ISNULL(gwl.total_labor, swl.total_labor) as total_labor
FROM #tmp_pm_aggregate t
JOIN facilities f
ON t.facility_id = f.id
JOIN risks r
ON t.risk_id = r.id
JOIN users u
ON t.user_id = u.id
LEFT JOIN (SELECT wl.record_id, wl.user_id, SUM(wl.labor_time) as total_labor
FROM work_logs wl
WHERE wl.type = 'single_pm'
GROUP BY wl.record_id, wl.user_id) as swl
ON t.pm_id = swl.record_id
AND t.user_id = swl.user_id
AND t.grouped_pm = false
LEFT JOIN (SELECT wl.record_id, wl.user_id, SUM(wl.labor_time) as total_labor
FROM work_logs wl
WHERE wl.type = 'grouped_pm'
GROUP BY wl.record_id, wl.user_id) as gwl
ON t.pm_id = gwl.record_id
AND t.user_id = gwl.user_id
AND t.grouped_pm = true
ORDER BY facility,
assignee,
risk;
DROP TABLE #tmp_pm_aggregate;
You can create an inline Table Valued Function, and simply return a resultset from it. You do not need (and cannot use) a temp table, you do not declare the returned "rowset" shape.
For the array parameters, you can use a Table Type:
CREATE TYPE dbo.GuidList (value uniqueidentifier NOT NULL PRIMARY KEY);
Because the table parameters are actual tables, you must query them like this (NOT EXISTS (SELECT 1 FROM #risk_ids) OR ISNULL(gp.risk_id, a.risk_id) IN (SELECT r.value FROM #risk_ids))
The parameters must start with #
There is no boolean type, you must use bit
Always use deterministic date formats for literals. yyyymmdd works for dates. Do you need to take into account hours and minutes, because you haven't?
ISNULL generally performs better than COALESCE in SQL Server, as the compiler understands it better
You may want to pass a separate parameter showing whether you passed in anything for the optional table parameters
I suggest you look carefully at the actual query: why does it need DISTINCT? It performs poorly, and is usually a code-smell indicating poorly thought-out joins. Perhaps you need to combine the two joins on assignees, or perhaps you should use a row-numbering strategy somewhere.
CREATE FUNCTION dbo.pm_aggregate_report
(
#facility_ids dbo.GuidList
, #risk_ids dbo.GuidList
, #assignee_ids dbo.GuidList
, #start_date date
, #end_date date
)
RETURNS TABLE AS RETURN
SELECT DISTINCT -- why DISTINCT, perhaps rethink your joins
ISNULL(gp.facility_id, a.facility_id) as facility_id,
ISNULL(p.grouped_pm_id, p.id) as pm_id,
CASE WHEN p.grouped_pm_id IS NULL THEN CAST(0 AS bit) ELSE CAST(1 AS bit) END as grouped_pm,
ISNULL(gp.risk_id, a.risk_id) as risk_id,
ISNULL(gp.pm_status_id, p.pm_status_id) as pm_status_id,
ISNULL(gass.user_id, sass.user_id) as user_id,
ISNULL(gp.completed_by, p.completed_by) as completed_by
FROM pms p
JOIN assets a
ON p.asset_id = a.id
LEFT JOIN grouped_pms gp
ON p.grouped_pm_id = gp.id
LEFT JOIN assignees sass
ON p.id = sass.record_id
AND sass.type = 'single_pm'
LEFT JOIN assignees gass
ON p.grouped_pm_id = gass.record_id
AND gass.type = 'grouped_pm'
LEFT JOIN users u
ON (sass.user_id = u.id OR gass.user_id = u.id) -- is this doubling up your rows?
WHERE a.facility_id IN (SELECT f.value FROM #facility_ids f)
AND a.is_component = 0
AND ISNULL(gp.pm_status_id, p.pm_status_id) in ('f9bdfc17-3bb5-4ec0-8477-24ef05ea3b9b', '06fc910c-3d07-4284-8f6e-8fb3873f5333')
AND ISNULL(gp.completion_date, p.completion_date) BETWEEN ISNULL(#start_date, '20000101') AND ISNULL(#end_date, '30000101') -- perhaps use >= AND <
AND ISNULL(gp.show_date, p.show_date) <= CURRENT_TIMESTAMP
AND ISNULL(gass.user_id, sass.user_id) IS NOT NULL
AND u.user_type_id != 'ec823d98-7023-4908-8006-2e33ddf2c11b'
AND (NOT EXISTS (SELECT 1 FROM #risk_ids) OR ISNULL(gp.risk_id, a.risk_id) IN (SELECT r.value FROM #risk_ids))
AND (NOT EXISTS (SELECT 1 FROM #assignee_ids) OR ISNULL(gass.user_id, sass.user_id) IN (SELECT aid.value FROM #assignee_ids aid));
I know that there are quite many threads on "Windowed functions can only appear in the select or ORDER BY clases" topic, but I have read them through and just don't seem to get any of those trick to work for me. So here I go.
My Query you can see below the line. I have highlighted the part of the Query which is "causing" me issues or problems. The thing is that I would like to get
"LocalCurrentAmount not between -1.000000 and 1.000000"
in somehow. I have tried the CTE versioon, but somehow didn't work and my declare tables and then the details view started causing problems.
Would really appreciate your help!
Jaanis
declare #exceptions1 table (CustomerCode varchar(7), Exception_comment varchar(15));
insert into #exceptions1 (CustomerCode, Exception_comment)
VALUES
(3514437,'Exception'),(3500977,'Exception'),(3295142,'Exception'), ...
declare #exceptions2 table (CustomerCode2 varchar(7), Exception_comment2 varchar(15));
insert into #exceptions2 (CustomerCode2, Exception_comment2)
VALUES
(3390437,'VIP SE') ,(3390438,'VIP SE') ,(3390481,'VIP SE'), ...
declare #exceptions3 table (CustomerCode3 varchar(7), Exception_comment3 varchar(15));
insert into #exceptions1 (CustomerCode, Exception_comment)
VALUES
(1530350, 'DK Exception'), (1533834, 'DK Exception'), (1530002, 'DK Exception'), ...
with Details as
(
select ard.AccountsReceivableHeaderID, sum(ard.TransactionAmountOC) as DetailAmountOC , Max(DetailSequenceCode) as DetailSequenceCode, Max( ard.BatchDate) as BatchDate
from dmbase.fAccountsReceivableDetail ard
join dmbase.fAccountsReceivable arh on ard.AccountsReceivableHeaderID = arh.AccountsReceivableID
where ard.BatchDate <= getdate()
group by AccountsReceivableHeaderID
)
SELECT
comp.CompanyCode
,convert(varchar(10),ar.InvoiceDate, 103) as Invoice_date -- dd/MM/yyyy format
,case
when ar.IsCreditMemo = 'Y' then 'Memo (Credit/Debit)'
when ar.InvoiceCode = '0' then 'Payment'
else 'Invoice'
end as Description
,isnull(cm.SummaryInvoiceCode, ar.InvoiceSummaryCode) InvoiceSummaryCode
,case
when len(ar.InvoiceSequenceCode) = '1' then CONCAT(ar.InvoiceCode,'-000',ar.InvoiceSequenceCode)
when len(ar.InvoiceSequenceCode) = '2' then CONCAT(ar.InvoiceCode,'-00',ar.InvoiceSequenceCode)
when len(ar.InvoiceSequenceCode) = '3' then CONCAT(ar.InvoiceCode,'-0',ar.InvoiceSequenceCode)
else CONCAT(ar.InvoiceCode,'-',ar.InvoiceSequenceCode)
end as Invoice#
,**(ar.OriginalInvoiceAmountOC
+
case
when row_number() over (partition by AccountsReceivableID order by ar.InvoiceCode) = 1 then isnull(vat.vatAdjustment, 0)
else 0
end
+
coalesce(det.DetailAmountOC, 0)) * coalesce(cer.CurrencyExchangeRate, ar.CurrencyExchangeRate) AS LocalCurrentAmount**
,(ar.OriginalInvoiceAmountOC
+
case
when row_number() over (partition by AccountsReceivableID order by ar.InvoiceCode) = 1 then isnull(vat.vatAdjustment, 0)
else 0
end
+ coalesce(det.DetailAmountOC, 0)) AS CurrentAmount
,ar.OriginalInvoiceAmountOC
+
case
when row_number() over (partition by AccountsReceivableID order by ar.InvoiceCode) = 1 then isnull(vat.vatAdjustment, 0)
else 0
end as OriginalInvoiceAmountOC
,ar.InvoiceCurrencyCode
,cust.CustomerCode
,upper(cust.CustomerName) as CustomerName
from
dmbase.fAccountsReceivable ar
INNER JOIN dmbase.dlocation loc
ON loc.LocationID = ar.LocationID
INNER JOIN dmbase.dCustomer cust
ON cust.CustomerID = ar.CustomerID
LEFT JOIN dmbase.VatAdjustment vat
on ar.InvoiceCode = vat.contractNumber
and ar.InvoiceSequenceCode = vat.invoiceSequence
and cust.CustomerCode = vat.CustomerNumber
and loc.CompanyCode = vat.companyCode
inner join dmbase.dCompany comp
on (ar.CompanyID = comp.CompanyID)
left join dmbase.dAccountsReceivableInvoiceStatus aris
on (aris.ARInvoiceStatusAMID=ar.ARInvoiceStatusAMID)
left hash join Details det
on (ar.AccountsReceivableID = det.AccountsReceivableHeaderID)
left join dmbase.dCurrencyExchangeRate cer
on (comp.CompanyCode = cer.CompanyCode
and ar.InvoiceCurrencyCode = cer.CurrencyCode
and case ar.InvoiceDate when '1900-01-01' then getdate() else ar.InvoiceDate end between cer.ValidFrom and cer.ValidTo)
left join dmbase.fContractClosedHeader ccd
on ccd.ContractNumber = ar.InvoiceCode
and ccd.ContractSeqNumber = ar.InvoiceSequenceCode
and ccd.CompanyID = ar.CompanyID
and ccd.ContractNumber!='0'
and ccd.CreditMemoContractNumber != '0'
left join dmbase.fAccountsReceivableHeader cm
on ccd.CreditMemoContractNumber = cm.ContractNumber
and ccd.CreditMemoSequenceCode = cm.ContractSeqNumber
and cm.CompanyID = ccd.CompanyID
where
(aris.ARInvoiceStatusCode = 'OP' or (ar.LastPaymentDate >= getdate())
or (ar.TotalAdjustmentsAmountOC <> 0 and ar.CurrentAmountLC = 0
and (ar.OriginalInvoiceAmountOC + isnull(vat.vatAdjustment, 0) ) + coalesce(det.DetailAmountOC, 0) <> 0)
)
and ar.OriginalInvoiceAmountOC <= 0
and ar.IsCreditMemo = 'Y' -- ainult Memo (Credit/Debit)
and cust.InternalCustomerType = 'External'
and cust.CustomerName not in ('RR AJM', 'RAMIRENT', 'Ramirent')
and cust.CustomerName not like '%[7][0-9][0-9][0-9]%'
and ar.InvoiceDate <= EOMONTH(getdate(),-3
and cust.CustomerCode NOT IN
(select CustomerCode from #exceptions1
union
select CustomerCode2 from #exceptions2
union
select CustomerCode3 from #exceptions3)
order by Invoice_date
When using a Window function, like you said in your post, you can't use it in the WHERE clause. The common solution, therefore, is to use a CTE and reference it in the WHERE outside of it. I've used your CTE, however, without any kind of sample data this is a total guess. I've also left a lot of comments for you, and changed some other parts of the SQL, as some of the clauses you have will effect your query's performance.
WITH
Details AS
(SELECT ard.AccountsReceivableHeaderID,
SUM(ard.TransactionAmountOC) AS DetailAmountOC,
MAX(DetailSequenceCode) AS DetailSequenceCode,
MAX(ard.BatchDate) AS BatchDate
FROM dmbase.fAccountsReceivableDetail ard
JOIN dmbase.fAccountsReceivable arh ON ard.AccountsReceivableHeaderID = arh.AccountsReceivableID
WHERE ard.BatchDate <= GETDATE()
GROUP BY AccountsReceivableHeaderID),
Summary AS(
SELECT comp.CompanyCode,
CONVERT(varchar(10), ar.InvoiceDate, 103) AS Invoice_date, -- dd/MM/yyyy format
CASE
WHEN ar.IsCreditMemo = 'Y' THEN 'Memo (Credit/Debit)'
WHEN ar.InvoiceCode = '0' THEN 'Payment'
ELSE 'Invoice'
END AS Description,
ISNULL(cm.SummaryInvoiceCode, ar.InvoiceSummaryCode) AS InvoiceSummaryCode,
CASE
WHEN LEN(ar.InvoiceSequenceCode) = '1' THEN CONCAT(ar.InvoiceCode, '-000', ar.InvoiceSequenceCode)
WHEN LEN(ar.InvoiceSequenceCode) = '2' THEN CONCAT(ar.InvoiceCode, '-00', ar.InvoiceSequenceCode)
WHEN LEN(ar.InvoiceSequenceCode) = '3' THEN CONCAT(ar.InvoiceCode, '-0', ar.InvoiceSequenceCode)
ELSE CONCAT(ar.InvoiceCode, '-', ar.InvoiceSequenceCode)
END AS Invoice#,
(ar.OriginalInvoiceAmountOC + CASE
WHEN ROW_NUMBER() OVER (PARTITION BY AccountsReceivableID ORDER BY ar.InvoiceCode) = 1 THEN ISNULL(vat.vatAdjustment, 0)
ELSE 0
END + COALESCE(det.DetailAmountOC, 0)) * COALESCE(cer.CurrencyExchangeRate, ar.CurrencyExchangeRate) AS LocalCurrentAmount,
(ar.OriginalInvoiceAmountOC + CASE
WHEN ROW_NUMBER() OVER (PARTITION BY AccountsReceivableID ORDER BY ar.InvoiceCode) = 1 THEN ISNULL(vat.vatAdjustment, 0)
ELSE 0
END + COALESCE(det.DetailAmountOC, 0)) AS CurrentAmount,
ar.OriginalInvoiceAmountOC + CASE
WHEN ROW_NUMBER() OVER (PARTITION BY AccountsReceivableID ORDER BY ar.InvoiceCode) = 1 THEN ISNULL(vat.vatAdjustment, 0)
ELSE 0
END AS OriginalInvoiceAmountOC,
ar.InvoiceCurrencyCode,
cust.CustomerCode,
UPPER(cust.CustomerName) AS CustomerName
FROM dmbase.fAccountsReceivable ar
INNER JOIN dmbase.dlocation loc ON loc.LocationID = ar.LocationID
INNER JOIN dmbase.dCustomer cust ON cust.CustomerID = ar.CustomerID
LEFT JOIN dmbase.VatAdjustment vat ON ar.InvoiceCode = vat.contractNumber
AND ar.InvoiceSequenceCode = vat.invoiceSequence
AND cust.CustomerCode = vat.CustomerNumber
AND loc.CompanyCode = vat.companyCode
INNER JOIN dmbase.dCompany comp ON (ar.CompanyID = comp.CompanyID)
LEFT JOIN dmbase.dAccountsReceivableInvoiceStatus aris ON (aris.ARInvoiceStatusAMID = ar.ARInvoiceStatusAMID)
LEFT HASH JOIN Details det ON (ar.AccountsReceivableID = det.AccountsReceivableHeaderID)
LEFT JOIN dmbase.dCurrencyExchangeRate cer ON (comp.CompanyCode = cer.CompanyCode
AND ar.InvoiceCurrencyCode = cer.CurrencyCode
AND CASE ar.InvoiceDate WHEN '1900-01-01' THEN GETDATE()ELSE ar.InvoiceDate END BETWEEN cer.ValidFrom AND cer.ValidTo)
LEFT JOIN dmbase.fContractClosedHeader ccd ON ccd.ContractNumber = ar.InvoiceCode
AND ccd.ContractSeqNumber = ar.InvoiceSequenceCode
AND ccd.CompanyID = ar.CompanyID
AND ccd.ContractNumber != '0'
AND ccd.CreditMemoContractNumber != '0'
LEFT JOIN dmbase.fAccountsReceivableHeader cm ON ccd.CreditMemoContractNumber = cm.ContractNumber
AND ccd.CreditMemoSequenceCode = cm.ContractSeqNumber
AND cm.CompanyID = ccd.CompanyID
WHERE (aris.ARInvoiceStatusCode = 'OP'
OR (ar.LastPaymentDate >= GETDATE())
OR (ar.TotalAdjustmentsAmountOC <> 0
AND ar.CurrentAmountLC = 0
AND (ar.OriginalInvoiceAmountOC + ISNULL(vat.vatAdjustment, 0)) + COALESCE(det.DetailAmountOC, 0) <> 0)) --Why ISNULL for one, COALESCE for the other? Both will make the query non-SARGable
AND ar.OriginalInvoiceAmountOC <= 0
AND ar.IsCreditMemo = 'Y' -- ainult Memo (Credit/Debit)
AND cust.InternalCustomerType = 'External'
AND cust.CustomerName NOT IN ('RR AJM', 'RAMIRENT', 'Ramirent')
AND cust.CustomerName NOT LIKE '%[7][0-9][0-9][0-9]%' --A leading wildcard is going to perform slow
AND ar.InvoiceDate <= EOMONTH(DATEADD(DAY, -3, GETDATE())) --I have changed this from EOMONTH(GETDATE(), -3 (which made no sense)
AND NOT EXISTS (SELECT 1
FROM #exceptions1 E
WHERE E.CustomerCode = cust.CustomerCode) --Changed to EXISTS binned UNION you should use UNION ALL if you're doing something like this, it'll be quicker)
AND NOT EXISTS (SELECT 1
FROM #exceptions2 E
WHERE E.CustomerCode = cust.CustomerCode) --Changed to EXISTS binned UNION (you should use UNION ALL if you're doing something like this, it'll be quicker)
AND NOT EXISTS (SELECT 1
FROM #exceptions3 E
WHERE E.CustomerCode = cust.CustomerCode)) --Changed to EXISTS binned UNION you should use UNION ALL if you're doing something like this, it'll be quicker)
SELECT *
FROM Summary
WHERE LocalCurrentAmount NOT BETWEEN -1 AND 1
ORDER BY Invoice_date;
It's worth noting that the above sql is completely untested. I do not have access to your server, or data, so I'm purely relying on "my eye" to note any errors.
SELECT
ROW_NUMBER() OVER (ORDER BY Vendor_PrimaryInfo.Vendor_ID ASC) AS RowNumber,
*
FROM
Unit_Table
INNER JOIN
Vendor_Base_Price ON Unit_Table.Unit_ID = Vendor_Base_Price.Unit_ID
INNER JOIN
Vendor_PrimaryInfo ON Vendor_Base_Price.Vendor_ID = Vendor_PrimaryInfo.Vendor_ID
INNER JOIN
Vendor_Registration ON Vendor_Base_Price.Vendor_ID = Vendor_Registration.Vendor_ID
AND Vendor_PrimaryInfo.Vendor_ID = Vendor_Registration.Vendor_ID
INNER JOIN
Category_Table ON Vendor_Registration.Category_ID = Category_Table.Category_ID
LEFT JOIN
Vendor_Value_Table ON Vendor_Registration.Vendor_ID = Vendor_Value_Table.Vendor_ID
LEFT JOIN
Feature_Table ON Vendor_Value_Table.Feature_ID = Feature_Table.Feature_ID
WHERE
Vendor_Registration.Category_ID = 5
AND Vendor_PrimaryInfo.City = 'City'
AND (value_text in ('sample value') or
(SELECT
CASE WHEN ISNUMERIC(value_text) = 1
THEN CAST(value_text AS INT)
ELSE -1
END) BETWEEN 0 AND 100)
As column has multiple values which may be text or may be int that's why I cast based on case. My question is: I just want to fetch the records either whose value is between 0 and 100 or value between 300 to 400 or value is like sample value.
I just want to place the condition after where clause and do not want to use column_name multiple time in between operator because these values are coming from url
Thanks in advance any help would be grateful.
You can try this way..
WHERE
Vendor_Registration.Category_ID = 5
AND Vendor_PrimaryInfo.City = 'City'
AND (value_text in ('sample value') or
(CASE WHEN (ISNUMERIC(value_text) = 1)
THEN CAST(value_text AS INT)
ELSE -1
END) BETWEEN 0 AND 100)
I have a query which gives me perfectly good results:
select
A.ID_acc, A.ID_us, A.st, table3.KFL,
'100' as myattribute,
'101' as my attribute2
from
SOURCE1 as A
left join
(select
table2.ID_us, table2.ID_acc,
CASE WHEN table2.KFL_type = 'KFL' THEN P.index_num ELSE table2.KFL_type END as KFL
from
(select
table1.ID_us, table1.ID_acc,
CASE WHEN sum(table1.count_kfl) > 1 THEN '9999' WHEN sum(table1.count_kfl) = 1 THEN 'KFL' END as KFL_type
from
(SELECT
ID_us, ID_acc, count(*) as count_kfl
FROM
payments
WHERE
index_num IN (200, 201, 203)
AND (date >= XXXX or date2 >= 'XXXXX')
GROUP BY
1, 2) as table1
group by
1, 2) as table2
join
SOURCE2 as P on table2.ID_us = P.ID_us
and table2.ID_acc = P.ID_acc
where
(P.date>= XXXX or P.date2 >= 'XXXXX')
and index_num in (201,201,203)
group by
1, 2
order by
1, 2) as table3 on table3.ID_us = A.ID_us
and table3.ID_acc = A.ID_acc
where
A.not_deleted >= XXXXXX
This query is not my main question, so I only copied it just to short brief, but I wondering how I can now add one more additional column (result of count operation) as the end of my first query? Just to do not making 2 separately and then mixing results. Naturally I don't want to influence on my earlier fields results.
I have second query which looks like this:
select A.ID_us, count(*)/2 as number
from
SOURCE1 as A
left join
SOURCE3 as B
on A.ID_acc = B.ID_acc
where A.date >= XXXX
group by 1
The link between those 2 queries is attribute ID_acc in SOURCE A which appear in first and in second query.
But don't have idea how do it?
select A.ID_acc, A.ID_us, A.st, table3.KFL, '100' as myattribute, '101' as my attribute2, NEWSOURCE.MYNEW_attribute
from SOURCE1 as A
left join
(
...
)
as table3 on table3.ID_us = A.ID_us and table3.ID_acc = A.ID_acc
where A.not_deleted >= XXXXXX
left join
(
.
.
.
)
as NEWSOURCE
Something like this of course, don't work:///
Have you tried a correlated subquery:
select A.ID_acc, A.ID_us, A.st, table3.KFL, '100' as myattribute,
'101' as my attribute2,
( select count(*)/2 as number from SOURCE1 as IA left join SOURCE3 as IB on
IA.ID_acc = IB.ID_acc and IA.ID_Acc = A.ID_Acc where IA.date >= XXXX ) as NewColumn
from ...
Note the use of new aliases in the correlated subquery.
I have a query that returns 6 rows and I want to aggregate the information to provide a single row with a count of instances. The without aggregate query returns the correct data but when I add a GroupBy and Count to the query it returns 2 rows.
The underlying ID (SR01.ReportKey) shown in the first result has two records so I think the Group By is somehow using this field in the grouping.
NOTE: The ReportKey is not actually used in the query I just had it in the first result for information purposes.
Question :
Any idea why the Group By is not grouping all the rows into a single result with a count of 6?
Without aggregate
Query :
SELECT
'Open' AS RecStatus,
ISNULL(UWZone.UWZoneID,'') AS ZoneID,
ISNULL(UWZone.UWZoneName,'') AS ZoneName,
Branch.BranchID,
ISNULL(Branch.BranchName,'') AS BranchName,
UW.UWID AS ServicingRep,
ISNULL(UW.UWName,'') + '/' + ISNULL(UA.UWName, '') AS RepName
FROM ProductivityRecommendations
INNER JOIN SR01 ON SR01.ReportKey = ProductivityRecommendations.ReportKey
LEFT JOIN UW ON SR01.Underwriter = UW.UWID
LEFT JOIN UW AS UA ON SR01.UA = UA.UWID
LEFT JOIN Branch ON SR01.ProdBranch = Branch.BranchID
LEFT JOIN UWZone ON UWZone.UWZoneAbbrev = Branch.UWZone
WHERE ISNULL(SR01.ServicingBranch,'-') <> '-'
AND ProductivityRecommendations.DateComplete BETWEEN #DateFrom AND #DateTo
AND ProductivityRecommendations.RecCriticality IN ('CRI', 'CCM')
AND ProductivityRecommendations.RecStatus IN ('N','O','U','A','R')
AND DateRecIssued IS NOT NULL
AND (#Zone IS NULL OR (UWZone.UWZoneID IN (SELECT val FROM ufn_SplitMax(#Zone ,','))))
AND (#Branch IS NULL OR (Branch.BranchID IN (SELECT val FROM ufn_SplitMax(#Branch ,','))))
AND (#RepID IS NULL OR (SR01.Underwriter IN(SELECT val FROM ufn_SplitMax(#RepID ,','))) OR #RepID IS NULL OR (SR01.UA IN(SELECT val FROM ufn_SplitMax(#RepID ,','))))
AND (#InsuredNumber IS NULL OR (ProductivityRecommendations.CustNum IN (SELECT val FROM ufn_SplitMax(#InsuredNumber ,','))))
Results :
Adding aggregates
Query :
SELECT
'Open' AS RecStatus,
ISNULL(UWZone.UWZoneID,'') AS ZoneID,
ISNULL(UWZone.UWZoneName,'') AS ZoneName,
Branch.BranchID,
ISNULL(Branch.BranchName,'') AS BranchName,
UW.UWID AS ServicingRep,
ISNULL(UW.UWName,'') + '/' + ISNULL(UA.UWName, '') AS RepName,
COUNT(ProductivityRecommendations.RecStatus) AS Requests
FROM ProductivityRecommendations
INNER JOIN SR01 ON SR01.ReportKey = ProductivityRecommendations.ReportKey
LEFT JOIN UW ON SR01.Underwriter = UW.UWID
LEFT JOIN UW AS UA ON SR01.UA = UA.UWID
LEFT JOIN Branch ON SR01.ProdBranch = Branch.BranchID
LEFT JOIN UWZone ON UWZone.UWZoneAbbrev = Branch.UWZone
WHERE ISNULL(SR01.ServicingBranch,'-') <> '-'
AND ProductivityRecommendations.DateComplete BETWEEN #DateFrom AND #DateTo
AND ProductivityRecommendations.RecCriticality IN ('CRI', 'CCM')
AND ProductivityRecommendations.RecStatus IN ('N','O','U','A','R')
AND DateRecIssued IS NOT NULL
AND (#Zone IS NULL OR (UWZone.UWZoneID IN (SELECT val FROM ufn_SplitMax(#Zone ,','))))
AND (#Branch IS NULL OR (Branch.BranchID IN (SELECT val FROM ufn_SplitMax(#Branch ,','))))
AND (#RepID IS NULL OR (SR01.Underwriter IN(SELECT val FROM ufn_SplitMax(#RepID ,','))) OR #RepID IS NULL OR (SR01.UA IN(SELECT val FROM ufn_SplitMax(#RepID ,','))))
AND (#InsuredNumber IS NULL OR (ProductivityRecommendations.CustNum IN (SELECT val FROM ufn_SplitMax(#InsuredNumber ,','))))
GROUP BY UWZone.UWZoneID, UWZone.UWZoneName, Branch.BranchID, Branch.BranchName, SR01.ServicingRep, UW.UWID, ISNULL(UW.UWName,'') + '/' + ISNULL(UA.UWName, '')
Results :
as #Johan said in a comment:
This will should give you 1 row only in your described senario:
GROUP BY
ISNULL(UWZone.UWZoneID,''),
ISNULL(UWZone.UWZoneName,''),
Branch.BranchID,
ISNULL(Branch.BranchName,'') ,
UW.UWID,
ISNULL(UW.UWName,''),
ISNULL(UA.UWName, '')
Try a "select distinct" of the columns that you are grouping by, and also a LEN to see if they have spaces or other char that are not seen, and also test for NULLs. Then, you decide how to handel these columns, using ISNULL, COALESCE, CASE, and/or WHERE statements, depending on what you need.