SQL takes too long to run - sql

Both a and c are the same table with 400 records. b and d are the same table too with 300 records. Yet takes about 4 mins to run this. How can I speed this up?
select a.docref
from a
left outer b
on a.cono=b.cono and a.tt=b.tt and a.docref=b.docref
where a.cono='VC'
and b.accn08='9005100'
and a.pstper=11609
and a.cbpref not in (select c.cbpref
from c
left outer join d
on c.cono=d.cono and c.tt=d.tt and c.docref=d.docref
where c.cono='VC'
and d.accn08='9005100'
and c.pstper=11609
and c.tt='RX')

The syntax NOT IN takes a bit more time. Try LEFT JOIN and add a condition where ID IS NULL :
SEELCT a.docref
FROM a
LEFT OUTER JOIN b
ON a.cono=b.cono
AND a.tt=b.tt
AND a.docref=b.docref
LEFT OUTER JOIN
(
SELECT c.cbpref
FROM c
LEFT OUTER JOIN d
ON c.cono=d.cono AND c.tt=d.tt AND c.docref=d.docref
WHERE c.cono='VC'
AND d.accn08='9005100'
AND c.pstper=11609
AND c.tt='RX'
)tb
ON tb.cbpref = a.cbpref
AND a.cbpref IS NULL
WHERE a.cono='VC'
AND b.accn08='9005100'
AND a.pstper=11609

Related

Optimize a SQL Server left join

I have this query:
SELECT *
FROM Licitaciones L
LEFT JOIN CPVLicitaciones C ON L.IDLicitacion = C.IDLicitador
WHERE (DateInserted>='2019-12-11' or DateUpdated>='2019-12-11')
The query takes about two minutes and there are not so many records
I would like to optimize this query but I don't have the knowledge to do it.
SELECT *
FROM Licitaciones L
LEFT JOIN
CPVLicitaciones C ON
L.IDLicitacion = C.IDLicitador
WHERE DateInserted>='2019-12-11'
UNION
SELECT *
FROM Licitaciones L
LEFT JOIN
CPVLicitaciones C ON
L.IDLicitacion = C.IDLicitador
WHERE DateUpdated>='2019-12-11'

Stored Procedure (T-SQL) Join multiple tables

I'm currently working on a t-sql query in Microsoft SQL Server Management Studio (SQL Server), which should gather data over several tables. In the end I'll need [OfferId] and [Label]. Do you have an idea on how to write those 4 query statements into 1?
SELECT a.OfferId AS [OfferId], a.OfferDataId AS [OfferDataId], b.DeliveryModelPoolId AS [DeliveryModelPoolId]
FROM [Offer].[Offer] a
INNER JOIN [Offer].[OfferData] b
ON a.OfferDataId = b.OfferDataId
OfferId | OfferDataId | DeliveryModelPoolId
1..........| 1..................| 4
SELECT a.DeliveryModelPoolId AS [DeliveryModelPoolId], b.PoolId AS [PoolId]
FROM [Offer].[OfferData] a
INNER JOIN [Offer].[Pool] b
ON a.DeliveryModelPoolId = b.PoolId
DeliveryModelPoolId | PoolId
4................................| 4
SELECT a.DeliveryModelId AS [DeliveryModelId]
FROM [Offer].[Delivery] a
INNER JOIN [Offer].[Pool] b
ON a.DeliveryModelPoolId = b.PoolId
DeliveryModelId
2
6
SELECT a.Label AS [Label]
FROM [Offer].[DeliveryModel] a
INNER JOIN [Offer].[DeliveryLabels] b
ON a.DeliveryModelId = b.DeliveryModelId
Label
Service Center
Delivery By Car
Thanks a lot! :)
If you are planning to reuse the query, I would put it into a view:
CREATE VIEW vWOfferData
AS
SELECT a.offerID, dl.label
FROM [Offer].[Offer] a
INNER JOIN [Offer].[OfferData] b
ON a.OfferDataId = b.OfferDataId
INNER JOIN [Offer].[Pool] p2
ON b.DeliveryModelPoolId = p2.PoolId
INNER JOIN [Offer].[Delivery] d3
ON d3.DeliveryModelPoolId = p2.PoolId
INNER JOIN [Offer].[DeliveryModel] dl
ON dl.DeliveryModelId = d3.DeliveryModelId
You can then use it as a table. For example:
SELECT * FROM vWOfferData
You can join more than once in a query
select a.offerID, dl.label
FROM [Offer].[Offer] a
INNER JOIN [Offer].[OfferData] b
ON a.OfferDataId = b.OfferDataId
inner join [Offer].[Pool] p2
ON b.DeliveryModelPoolId = p2.PoolId
inner join [Offer].[Delivery] d3
ON d3.DeliveryModelPoolId = p2.PoolId
inner join [Offer].[DeliveryModel] dl
on dl.DeliveryModelId = d3.DeliveryModelId

MS Access (via VB.NET) - convert linked attribute tables to columns in output

I've searched, and found a lot of similar things, but not quite what I'm looking for.
I have what are essentially a bunch of linked tables with attributes and values.
xxBio table
xxBio_ID xxBio_LINK
1 100
2 101
xx table
xxBio_LINK xxAttr_LINK
100 1000
101 2000
xxAttr table
xxAttr_LINK xxAttrCat_1_LINK xxAttrCat_2_LINK
1000 null 550
2000 650 null
xxAttrCat_1 table
xxAttrCat_1_LINK xxAttrCat_1_Description xxAttrCat_1_Value
650 wumpus 20
xxAttrCat_2 table
xxAttrCat_2_LINK xxAttrCat_2_Description xxAttrCat_2_Value
550 frith 30
OUTPUT NEEDS TO BE:
xxBio_ID frith wumpus
1 30 null
2 null 20
I can easily see how to get the result set with columns like attribute_name1, attribute_value1, attribute_name2, attribute_value2, and so forth.
SELECT xxBio.ID, xxAttrCat_1.xxAttrCat_1_Description, xxAttrCat_1.xxAttrCat_1_Value, xxAttrCat_2.xxAttrCat_2_Description, xxAttrCat_2.xxAttrCat_2_Value
FROM ((
(xx INNER JOIN xxBio ON xx.xxBio_LINK = xxBio.xxBio_LINK)
INNER JOIN xxAttr ON xx.xxAttr_LINK = xxAttr.xxAttr_LINK)
LEFT JOIN xxAttrCat_1 ON xxAttr.xxAttrCat_1_LINK = xxAttrCat_1.xxAttrCat_1_LINK)
LEFT JOIN xxAttrCat_2 ON xxAttr.xxAttrCat_2_LINK = xxAttrCat_2.xxAttrCat_2_LINK
But that's not what we need. We need the attribute names to be column names.
How do we achieve this?
Update to question:
It turned out that we misunderstood the requirements, so we had to take a different route and did not get to try the answers. I appreciate the help.
Put the SQL in a string and execute from VBA. (Dynamic SQL?)
sql = "SELECT xxBio.ID, " & xxAttrCat_1.xxAttrCat_1_Description & ", " & ...
Consider using IIF() conditional statements:
SELECT xxBio.ID,
IIF(xxAttrCat_1.xxAttrCat_1_Description = 'wumpus',
xxAttrCat_1.xxAttrCat_1_Value, NULL) As [wumpus],
IIF(xxAttrCat_2.xxAttrCat_2_Description = 'frith',
xxAttrCat_2.xxAttrCat_2_Value, NULL) As [frith]
FROM (((xx
INNER JOIN xxBio ON xx.xxBio_LINK = xxBio.xxBio_LINK)
INNER JOIN xxAttr ON xx.xxAttr_LINK = xxAttr.xxAttr_LINK)
LEFT JOIN xxAttrCat_1 ON xxAttr.xxAttrCat_1_LINK = xxAttrCat_1.xxAttrCat_1_LINK)
LEFT JOIN xxAttrCat_2 ON xxAttr.xxAttrCat_2_LINK = xxAttrCat_2.xxAttrCat_2_LINK
If each ID can have multiple values along same descriptions and you need to sum or average all corresponding values, then turn query into conditional aggregation (known as pivoting). Below also uses table aliases, a, b, c1, c2 for brevity and organization.
SELECT b.ID,
SUM(IIF(c1.xxAttrCat_1_Description='wumpus', c1.xxAttrCat_1_Value, NULL)) As [wumpus],
SUM(IIF(c2.xxAttrCat_2_Description='frith', c2.xxAttrCat_2_Value, NULL)) As [frith]
FROM (((xx
INNER JOIN xxBio b ON xx.xxBio_LINK = b.xxBio_LINK)
INNER JOIN xxAttr a ON xx.xxAttr_LINK = a.xxAttr_LINK)
LEFT JOIN xxAttrCat_1 c1 ON a.xxAttrCat_1_LINK = c1.xxAttrCat_1_LINK)
LEFT JOIN xxAttrCat_2 c2 ON a.xxAttrCat_2_LINK = c2.xxAttrCat_2_LINK
GROUP BY b.ID
And if such descriptions can be many use MS Access SQL's crosstab query. But since you have two categories, run a crosstab on each and save them as stored queries or views. Then, join together:
--CATEGORY 1
TRANSFORM SUM(c1.xxAttrCat_1_Value) AS SumOfValue
SELECT b.ID,
FROM ((xx
INNER JOIN xxBio b ON xx.xxBio_LINK = b.xxBio_LINK)
INNER JOIN xxAttr a ON xx.xxAttr_LINK = a.xxAttr_LINK)
LEFT JOIN xxAttrCat_1 c1 ON a.xxAttrCat_1_LINK = c1.xxAttrCat_1_LINK
GROUP BY b.ID
PIVOT c1.xxAttrCat_1_Description;
--CATEGORY 2
TRANSFORM SUM(c2.xxAttrCat_2_Value) AS SumOfValue
SELECT b.ID,
FROM ((xx
INNER JOIN xxBio b ON xx.xxBio_LINK = b.xxBio_LINK)
INNER JOIN xxAttr a ON xx.xxAttr_LINK = a.xxAttr_LINK)
LEFT JOIN xxAttrCat_2 c2 ON a.xxAttrCat_2_LINK = c2.xxAttrCat_2_LINK
GROUP BY b.ID
PIVOT c2.xxAttrCat_2_Description;
--CROSSTAB QUERIES JOIN
SELECT c1.*, c2.*
FROM Categ1CrossTabQ c1
INNER JOIN Categ1CrossTabQ c2
ON c1.ID = c2.ID;
Please note: comments above with double dash are not allowed in an Access query and only one statement is allowed in saved query. Access has a limit of 255 columns per table/query, so pivoted values greater than 255 will err out unless you use IN clause. Finally, you cannot use crosstabs as subqueries. And crosstabs are strictly an MS Access command and not used in other DBMS's.

how to select from query result in Firebird 1.5

i got this query for Firebird 1.5 :
select * from (
select
ddddd.name,
gggg.land,
dd.maskenkey,
ddd.name,
Sum(b.epreis*a.menge),
Sum((kx.epreis / lx.kurs) * a.menge),
sum(case when b.bverpa_id='1' then (a.menge*e.p_volume)/e.pcs_box else a.menge*e.P_PCS_20ST end) as jumlah
from brrcp a
left outer join baufpo b on a.baufpo_id_aufnrpos = b.id
left outer join brrc c on a.brrc_id_rgnr = c.id
left outer join bauf d on b.bauf_id_linkkey = d.id
left outer join bkunde dd on d.bkunde_id_kunr = dd.id
left outer join badr ddd on dd.badr_id_adrnr = ddd.id
left outer join bvert dddd on d.bvert_id = dddd.id
left outer join badr ddddd on dddd.badr_id = ddddd.id
left outer join bbesp kx on b.id = kx.baufpo_id_aufpos
left outer join bbes aa on kx.bbes_id_linkkey = aa.id
left outer join bsal yy on kx.bsal_id = yy.id
left outer join bwaer lx on kx.bwaer_id_waehrungk = lx.id
left outer join bplz zz on ddd.bplz_id_landplz = zz.id
left outer join bland gggg on zz.bland_id_landkennz = gggg.id
left outer join bsa e on a.bsa_id_artnr = e.id
where c.eta_shipment between '01/01/2015' and '6/30/2015'
and dd.maskenkey starting 'AS-' and d.cancel = 'N' and d.confirm = 'N' and aa.status_po <> 'C'
and d.auftrag = 'J' and a.rg_buchungsart Is Null
group by ddddd.name,gggg.land,dd.maskenkey,ddd.name) abc
How to fix its structure because when I want to execute this query, i will get error? Thank you !!
**Invalid token.
Dynamic SQL Error.
SQL error code = -104.
Token unknown - line 2, char 1.
select.**
You are using a select in the FROM clause, this is called a derived table, and you can't use derived tables in Firebird 1.5 or earlier.
This feature was introduced 9 years ago in Firebird 2.0. So if you want to use this in your queries, you should upgrade (and if you do, upgrade to Firebird 2.5.5). Before you upgrade, please make sure to read through the Firebird 2.0, 2.1 and 2.5 release notes and the Firebird 2 Migration & installation Notes for any compatibility changes that you need to take into account.
The query in your question itself doesn't need derived tables at all, just remove the outer SELECT * FROM (....) abc from your query, it has - as it is posted - no added value.

i m confuse about this query

What is the name|type of this query? Like inner join, outer join.
SELECT a.tutorial_id, a.tutorial_author, b.tutorial_count
FROM tutorials_tbl a, tcount_tbl b
WHERE a.tutorial_author = b.tutorial_author
It's an Implicit INNER JOIN most commonly found in older code. It is synonymous with:
SELECT a.tutorial_id,
a.tutorial_author,
b.tutorial_count
FROM tutorials_tbl a
INNER JOIN tcount_tbl b ON a.tutorial_author = b.tutorial_author
which is also synonymous with just using JOIN:
SELECT a.tutorial_id,
a.tutorial_author,
b.tutorial_count
FROM tutorials_tbl a
JOIN tcount_tbl b ON a.tutorial_author = b.tutorial_author