Stored Procedure (T-SQL) Join multiple tables - sql

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

Related

INNER JOIN IN MULTIPLE COLUMNS

img
Hi guys.
I'm developing a clinic management program, I had to join two tables TB_DOCTORS, and TB_SPECIALTY. the problem is; every doctor have more 4 specialties. How can I join the TB_DOCTORS table with more than a specialty
SELECT TB_DOCTORS.*,
S1.SPECIALITY_NAME AS SPECIALITY_NAME1,
S2.SPECIALITY_NAME AS SPECIALITY_NAME2,
S3.SPECIALITY_NAME AS SPECIALITY_NAME3,
S4.SPECIALITY_NAME AS SPECIALITY_NAME4
FROM TB_DOCTORS
LEFT OUTER JOIN TB_SPECIALTY S1 ON TB_DOCTORS.SPEC_ID1 = S1.SPECIALITY_ID
LEFT OUTER JOIN TB_SPECIALTY S2 ON TB_DOCTORS.SPEC_ID2 = S2.SPECIALITY_ID
LEFT OUTER JOIN TB_SPECIALTY S3 ON TB_DOCTORS.SPEC_ID3 = S3.SPECIALITY_ID
LEFT OUTER JOIN TB_SPECIALTY S4 ON TB_DOCTORS.SPEC_ID4 = S4.SPECIALITY_ID

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.

select query in subquery giving Column is invalid in the select list because it is not contained error

I have following query which i want to get sum counts for my data
SELECT
TI.[text] as zone,
YEAR (ER.Inserted) as [Year],
SUM(CONVERT(INT,DRT.RDRT)) as RDRT,
SUM(CONVERT(INT,DRT.FACT)) as FACT ,
SUM(CONVERT(INT,DRT.ERU)) as ERU,
(
SELECT COUNT(ER1.ReportID)
FROM dbo.EW_Reports ER1
INNER JOIN dbo.EW_Report_InformationManagement ERI ON ER1.ReportID = ERI.ReportID
INNER JOIN EW_Report_Country ERC1 ON ER1.ReportID = ERC1.ReportID
INNER JOIN ApplicationDB.dbo.Country C1 ON ERC1.CountryID = C1.countryId
INNER JOIN ApplicationDB.dbo.Region R1 ON C1.regionId = R1.regionId
INNER JOIN ApplicationDB.dbo.Zone Z1 ON R1.zoneId = Z1.zoneId
WHERE ERI.EmergencyAppeal IS NOT NULL
AND (YEAR ( ER1.Inserted) = YEAR ( ER.Inserted))
AND Z1.zoneId = Z.zoneId
) as emergencyAppeals
FROM EW_Reports ER
INNER JOIN EW_DisasterResponseTools DRT ON ER.ReportID = DRT.ReportID
INNER JOIN EW_Report_Country ERC ON ER.ReportID = ERC.ReportID
INNER JOIN ApplicationDB.dbo.Country C ON ERC.CountryID = c.countryId
INNER JOIN ApplicationDB.dbo.Region R ON c.regionId = R.regionId
INNER JOIN ApplicationDB.dbo.Zone Z ON R.zoneId = Z.zoneId
INNER JOIN ApplicationDB.dbo.Translation T ON Z.translationId = T.translationId
INNER JOIN ApplicationDB.dbo.TranslationItem TI ON T.translationId = TI.translationId
INNER JOIN EW_lofDisasterTypes D ON ER.DisasterTypeID = D.TranslationID AND D.LanguageID = 1 AND TI.languageID = 1
WHERE (YEAR ( ER.Inserted) IN (2011,2012))
GROUP BY TI.[text], YEAR (ER.Inserted)
But its giving following error
Column 'ApplicationDB.dbo.Zone.zoneId' is invalid in the select list
because it is not contained in either an aggregate function or the
GROUP BY clause.
Please assist me how to resolve this error .
there are too many ApplicationDB.dbo.Zone.zoneId records in your table already
simple add ApplicationDB.dbo.Zone.zoneId in group by then problem will solved
Select ....
.....
GROUP BY TI.[text], YEAR (ER.Inserted) ,ApplicationDB.dbo.Zone.zoneId
For your question why u need to add ApplicationDB.dbo.Zone.zoneId in my group as i am using that in ur subquery, this is because u perform a outer condition in your subquery
SELECT
----
(
SELECT
-----
INNER JOIN ApplicationDB.dbo.Zone Z1 ON R1.zoneId = Z1.zoneId
WHERE
----
AND Z1.zoneId = Z.zoneId
)
-----
INNER JOIN ApplicationDB.dbo.Zone Z ON R.zoneId = Z.zoneId
WHERE (YEAR ( ER.Inserted) IN (2011,2012))
------
note that you have a condition in different years
so your data flow may like this
ZoneID Years Record
1 2011 1000
1 2012 1000
same zone id contain different years, without proper grouping, sql got no way to group years column
it is showing the error because you have used this in sub query where condition
you need toadd ApplicationDB.dbo.Zone.zoneId in group by

SQL Server update with joins

I am trying to update a date in a table, based off of a MAX(date) in another table. To get the correct data to link up, I have to do 2 inner joins and 2 left outer joins.
I can select the correct data, it returns a Guid (PersonId) and the Date.
I have to use this information to update my original table. I am having trouble getting this to work, I still getting syntax errors.
update tblqualityassignments as assign
inner join tblrequirementteams as team on assign.guidmemberid = team.guidmemberid
set assign.dtmQAPCLed = dtmTaken
from
(
select reg.guidpersonid, max(certs.dtmTaken) as dtmTaken from tblqualityassignments as assign
inner join tblrequirementteams as team on assign.guidmemberid = team.guidmemberid
inner join tblregisteredusercerts as reg on team.guidpersonid = reg.guidpersonid
left outer join tblcerttaken as certs on certs.guidcertid = reg.guidcertid
left outer join tblCodesCertType as types on types.intcerttypeid = certs.intcerttypeid
where types.intcerttypeid = 1
and assign.guidmemberid = team.guidmemberid
group by reg.guidpersonid as data
)
where data.guidpersonid = team.guidpersonid
Assuming you are using SQL Server for this, then this should work:
UPDATE A
SET A.dtmQAPCLed = dtmTaken
FROM tblqualityassignments AS A
INNER JOIN tblrequirementteams as T
ON A.guidmemberid = T.guidmemberid
INNER JOIN (select reg.guidpersonid, max(certs.dtmTaken) as dtmTaken
from tblqualityassignments as assign
inner join tblrequirementteams as team
on assign.guidmemberid = team.guidmemberid
inner join tblregisteredusercerts as reg
on team.guidpersonid = reg.guidpersonid
left outer join tblcerttaken as certs
on certs.guidcertid = reg.guidcertid
left outer join tblCodesCertType as [types]
on [types].intcerttypeid = certs.intcerttypeid
where [types].intcerttypeid = 1
and assign.guidmemberid = team.guidmemberid
group by reg.guidpersonid) data
ON T.guidpersonid = data.guidpersonid