How to optimize long running cte - sql

I have one query that is taking 10 minute and giving me 6852104 records. How can I optimize it? I have added execution plan as well.
My query is like this:
WITH CTE (columns name
)
AS (
SELECT columns
FROM #tempTable b WITH (NOLOCK)
INNER JOIN physicaltable1 A ON A.ParentInvoiceItemId = b.InvoiceItemId
INNER JOIN physicaltable2 c ON c.LinkedInvoiceItemId = a.LinkedInvoiceItemId
AND c.HospitalId = B.Hospital_Id
UNION ALL
SELECT columns
FROM CTE LIP
JOIN physicaltable1 LIC ON LIP.ChildInvoiceItemId = LIC.ParentInvoiceItemId
INNER JOIN physicaltable12 LIH ON LIH.LinkedInvoiceItemId = LIC.LinkedInvoiceItemId
AND LIH.HospitalId = LIP.HospitalId
WHERE LIP.[Level] < 3
)
SELECT *
INTO #newtemptable
FROM CTE;

Related

Correct Syntax When Limiting Results in Sybase SQL Statement Query

I am trying to put a limit on my Sybase SELECT statement query, but I keep getting syntax errors. I've tried using both limit and SELECT * TOP 10, but neither seems to work. This is my SELECT statement code:
SELECT top 10 *
// column params
FROM claims c
LEFT OUTER JOIN claims_transaction as ct
ON ct.claim_id = c.id
LEFT OUTER JOIN claims_batch_listings cb
ON cb.batch_listing = c.batchl
LEFT OUTER JOIN notes_details d
ON d.id_number = c.notes_detail_id
LEFT OUTER JOIN individual_ins_xref px
ON px.pt_id = c.ind_id
AND px.ins_id = c.ins_id
LEFT OUTER JOIN individuals ind
ON ind.id_number = c.ind_id
LEFT OUTER JOIN sections sec
ON ind.sec_id = sec.id_number
LEFT OUTER JOIN contract_items cont
ON c.contract_id = cont.contract_id
WHERE ( d.date_of_visit >= px.coverage_start AND d.date_of_visit <= px.coverage_end )
AND visit_type <> 'No Visit'
ORDER BY c.datetimecreated;
The * is wrong. Just lose it and you should be OK:
SELECT top 10 -- * removed here
c.claim_problem as problem,
-- etc.

Using an Inner join select statement

I am fairly new to SQL. I have created an inner join between 2 tables and further created some where clauses to pull out the appropriate data. As I understand it I have used an inner join to connect 2 tables. What I am trying to do now is connect my resultant select query to another table. How would I do this?
SELECT
t.[Type]
from [MITS].[dbo].[monster] t
inner join (
SELECT [MITS].[dbo].[BROKERTABLE].[BrokerID]
,[MITS].[dbo].[CustomerRates].[MPAN_ID]
,[MITS].[dbo].[BROKERTABLE].[Commission_Rate]
,[MITS].[dbo].[BROKERTABLE].[Rate_From]
,[MITS].[dbo].[BROKERTABLE].[Rate_To]
,[MITS].[dbo].[CustomerRates].[From_Date]
,[MITS].[dbo].[CustomerRates].[To_Date]
from [MITS].[dbo].[CustomerRates]
Inner Join [MITS].[dbo].[BROKERTABLE]
on [MITS].[dbo].[BROKERTABLE].[MPAN_ID] =
[MITS].[dbo].[CustomerRates].[MPAN_ID]
where
[MITS].[dbo].[CustomerRates].[To_Date] <=
[MITS].[dbo].[BROKERTABLE].[Rate_To]
and
convert(datetime,'01/11/2015',103)
between convert(datetime,[MITS].[dbo].[CustomerRates].[From_Date],103)
and convert(datetime,[MITS].[dbo].[CustomerRates].[To_Date],103)
) d on t.MITID = d.MPAT_ID
Add extra table into existing query: guess 1
select *
from atable a
inner join btable b on a.somecol = b.somecol
inner join extra_table t on a.somecol = t.somecol and b.somecol = t.somecol2
Add existing query to a table, method 1
select *
from extra_table t
inner join (
your existing query here
) d on t.somecol = d.somecol
Add existing query to a table, method 2
select *
from (
your existing query here
) d
inner join extra_table t on d.somecol = t.somecol

Join two select queries horizontally in Postgresql

I have following two queries:
Query #1:
(SELECT
pl.c_project_Id, pl.c_projectphase_Id, pl.c_projecttask_Id, pl.m_product_Id,
pj.name as projectname, ph.name as phasename, pt.name as taskname, pd.name as prodname,
round(pl.plannedqty, 2) as planqty, round(pl.plannedprice, 2) as planrate,
round(pl.plannedamt, 2) as planamt
FROM adempiere.c_projectline pl
LEFT JOIN adempiere.c_project pj ON pl.c_project_id = pj.c_project_id
LEFT JOIN adempiere.c_projectphase ph ON pl.c_projectphase_id = ph.c_projectphase_id
LEFT JOIN adempiere.c_projecttask pt ON pl.c_projecttask_id = pt.c_projecttask_id
LEFT JOIN adempiere.m_product pd ON pl.m_product_id = pd.m_product_id
WHERE pl.c_project_id = 1000001 AND pl.ad_client_id = 1000000
ORDER BY ph.c_projectphase_id, pt.c_projecttask_id)
Output is: 11 columns and 16 rows
Query #2:
(SELECT
fa.c_project_id, fa.c_projectphase_id, fa.c_projecttask_id, fa.m_product_id,
pj.name as costprojectname, ph.name as costphasename, pt.name as costtaskname,
pd.name as costprodname,
abs(fa.qty) as costqty, round((fa.amtacctdr/fa.qty), 2) as costrate,
round(sum(fa.amtacctdr), 0) as costamt
FROM adempiere.fact_acct fa
LEFT JOIN adempiere.c_project pj ON fa.c_project_id = pj.c_project_id
LEFT JOIN adempiere.c_projectphase ph ON fa.c_projectphase_id = ph.c_projectphase_id
LEFT JOIN adempiere.c_projecttask pt ON fa.c_projecttask_id = pt.c_projecttask_id
LEFT JOIN adempiere.m_product pd ON fa.m_product_id = pd.m_product_id
WHERE fa.c_project_id = 1000001 AND (fa.gl_category_id = 1000006 OR fa.gl_category_id = 1000005)
AND fa.qty > 0 AND fa.c_project_id is not null
GROUP BY fa.m_product_id, fa.c_project_id, fa.c_projectphase_id, fa.c_projecttask_id,
fa.qty, fa.amtacctdr,
pj.name, ph.name, pt.name, pd.name)
Output is: 11 columns and 6 rows
I want to join these queries horizontally, display all columns but rows should not duplicate. As when I apply union to join them the result shows duplicate rows. How can I cope with this issue?
You should be able to join queries like this:
select * from
(
<your first query here>
) tbl1
join (
<your second query here>
) tbl2
on tbl1.c_project_Id = tbl2.c_project_Id
and tbl1.c_projectphase_Id = tbl2.c_projectphase_Id -- you might add or
and tbl1.c_projecttask_Id = tbl2.c_projecttask_Id -- remove join criteria
and tbl1.m_product_Id = tbl2.m_product_Id -- here

SQL - UNION, priority on the first select statement when doing order by

I'm trying to print out the results from the "GermanDB" Database first, while also showing everything from the Boston DB that was not in the German database. Can this be done in one query?
My query (the bold part functions but does not order the way I want)
select * from (
SELECT DISTINCT a.ProductRef
FROM GERMANDB.dbo.LOCATIONS AS a INNER JOIN GERMANDB.dbo.ITEMS AS b ON a.ProductRef = b.ProductRef
WHERE b.ACTIVE=1
) ta
UNION select * from
SELECT DISTINCT c.ProductRef
FROM BOSTONDB.dbo.LOCATIONS AS c INNER JOIN BOSTONDB.dbo.ITEMS AS d ON c.ProductRef = d.ProductRef
WHERE c.ACTIVE=1 (c.ProductRef NOT IN
(SELECT ProductRef FROM GERMANDB.dbo.ITEMS where ACTIVE=1))
) tb
order by ta.ProductRef** , tb.productRef
Just add one field to signal the priority. Like this:
select *, 0 as Priority from (
SELECT DISTINCT a.ProductRef
FROM GERMANDB.dbo.LOCATIONS AS a INNER JOIN GERMANDB.dbo.ITEMS AS b ON a.ProductRef = b.ProductRef
WHERE b.ACTIVE=1
) ta
UNION select *, 1 as Priority from
SELECT DISTINCT c.ProductRef
FROM BOSTONDB.dbo.LOCATIONS AS c INNER JOIN BOSTONDB.dbo.ITEMS AS d ON c.ProductRef = d.ProductRef
WHERE c.ACTIVE=1 (c.ProductRef NOT IN
(SELECT ProductRef FROM GERMANDB.dbo.ITEMS where ACTIVE=1))
) tb
order by Priority, ProductRef

selecting the max values based on a count

How can i retrieve the max of each ValueCount based on the firmid. I need the data to be output like so.
My code is below
SELECT
F.FirmID,
F.Name,
DL.ValueId,
DL.ValueName,
count(DL.ValueName) AS ValueCount
FROM
dbo.Jobs AS J
INNER JOIN DimensionValues AS DV ON
DV.CrossRef = J.JobId
INNER JOIN dbo.DimensionLists AS DL ON
DV.ValueId = DL.ValueId
INNER JOIN Firms AS F ON
F.FirmId = J.ClientFirmId
WHERE
DL.DimensionId = 4
GROUP BY
F.FirmID,
F.Name,
DL.ValueName,
DL.ValueId
this produces something like
firmid | value | count
1 1 5
1 2 10
2 3 1
2 1 6
i need to return back the records with 10 and 6.
EDIT : SQL 2005 answer deleted.
Then you could push your results into a temporary table (or table variable) and do something like this...
SELECT
*
FROM
TempTable
WHERE
ValueCount = (SELECT MAX(ValueCount) FROM TempTable AS Lookup WHERE FirmID = TempTable.FirmID)
Or...
SELECT
*
FROM
TempTable
INNER JOIN
(SELECT FirmID, MAX(ValueCount) AS ValueCount FROM TempTable GROUP BY FirmID) AS lookup
ON lookup.FirmID = TempTable.FirmID
AND lookup.ValueCount = TempTable.ValueCount
These will give multiple records if any ValueCount is tied with another for the same FirmID. As such, you could try this...
SELECT
*
FROM
TempTable
WHERE
value = (
SELECT TOP 1
value
FROM
TempTable as lookup
WHERE
FirmID = TempTable.FirmID
ORDER BY
ValueCount DESC
)
For this problem you need to produce the result set of the query in order to determine the Max ValueCount, then you need to do the query again to pull just the records with Max ValueCount. You can do this many way, like repeating the main query as subqueries, and in SQL Server 2005/2008 by using a CTE. I think using the subqueries gets a little messy and would prefer the CTE, but for SQL Server 2000 you don't have that as an option. So, I've used a temp table instead of a CTE. I run it once to get the MaxValueCount and save that into a temp table, then run the query again and join against the temp table to get just the record with MaxValueCount.
create table #tempMax
(
FirmID int,
MaxValueCount int
)
insert #tempMax
SELECT t.FirmID, MAX(t.ValueCount) AS MaxValueCount
FROM (
SELECT F.FirmID, F.Name, DL.ValueId, DL.ValueName
, count(DL.ValueName) AS ValueCount
FROM dbo.Jobs AS J
INNER JOIN DimensionValues AS DV ON DV.CrossRef = J.JobId
INNER JOIN dbo.DimensionLists AS DL ON DV.ValueId = DL.ValueId
INNER JOIN Firms AS F ON F.FirmId = J.ClientFirmId
WHERE DL.DimensionId = 4
GROUP BY F.FirmID, F.Name, DL.ValueName, DL.ValueId) t
SELECT t.FirmID, t.Name, t.ValueID, t.ValueName, t.ValueCount
FROM (
SELECT F.FirmID, F.Name, DL.ValueId, DL.ValueName
, count(DL.ValueName) AS ValueCount
FROM dbo.Jobs AS J
INNER JOIN DimensionValues AS DV ON DV.CrossRef = J.JobId
INNER JOIN dbo.DimensionLists AS DL ON DV.ValueId = DL.ValueId
INNER JOIN Firms AS F ON F.FirmId = J.ClientFirmId
WHERE DL.DimensionId = 4
GROUP BY F.FirmID, F.Name, DL.ValueName, DL.ValueId) t
INNER JOIN #tempMax m ON t.FirmID = m.FirmID and t.ValueCount = m.MaxValueCount
DROP TABLE #tempMax
You should be able to use a derived table for this:
SELECT F.FirmID,
F.Name,
DL.ValueId,
DL.ValueName,
T.ValueCount
FROM Jobs J
INNER JOIN DimensionValues DV
ON DV.Crossref = J.JobID
INNER JOIN DimensionList DL
ON DV.ValueID = DL.ValueID
INNER JOIN Firms F
ON F.FirmID = J.ClientFirmID
--derived table
INNER JOIN (SELECT FirmID, MAX(ValueName) ValueCount FROM DimensionList GROUP BY FirmID) T
ON T.FirmID = F.FirmID
WHERE DL.DimensionId = 4
TBL1 and TBL2 is your query:
SELECT *
FROM TBL1
WHERE
TBL1.ValueCount = (SELECT MAX(TBL2.ValueCount) FROM TBL2 WHERE TBL2.FIRMID = TBL1.FIRMID)