SQL using data field twice - tsql

I currently have the following:
SELECT TblSchoolManagementForms.txtForm, TblPupilManagementPupils.txtSchoolID, TblPupilManagementPupils.txtSurname, TblPupilManagementPupils.txtForename,
TblStaff.Fullname AS TutorFullName, TblStaff.SchoolEmailAddress, TblSchoolManagementYears.txtYearTutor, TblSchoolManagementYears.txtAsstYearTutor
FROM TblPupilManagementPupils INNER JOIN
TblSchoolManagementForms ON TblPupilManagementPupils.txtForm = TblSchoolManagementForms.txtForm INNER JOIN
TblStaff ON TblSchoolManagementForms.txtFormTutor = TblStaff.User_Code INNER JOIN
TblSchoolManagementYears ON TblPupilManagementPupils.intNCYear = TblSchoolManagementYears.intNCYear AND
TblSchoolManagementForms.intNCYear = TblSchoolManagementYears.intNCYear
WHERE TblSchoolManagementYears.intNCYear > 6
UNION
SELECT TblSchoolManagementForms.txtForm, TblPupilManagementPupils.txtSchoolID, TblPupilManagementPupils.txtSurname, TblPupilManagementPupils.txtForename,
TblStaff.Fullname AS TutorFullName, TblStaff.SchoolEmailAddress, TblSchoolManagementYears.txtYearTutor, TblSchoolManagementYears.txtAsstYearTutor
FROM TblPupilManagementPupils INNER JOIN
TblSchoolManagementForms ON TblPupilManagementPupils.txtForm = TblSchoolManagementForms.txtForm INNER JOIN
TblStaff ON TblSchoolManagementForms.txtAsstFormTutor = TblStaff.User_Code INNER JOIN
TblSchoolManagementYears ON TblPupilManagementPupils.intNCYear = TblSchoolManagementYears.intNCYear AND
TblSchoolManagementForms.intNCYear = TblSchoolManagementYears.intNCYear
WHERE TblSchoolManagementYears.intNCYear > 6
This is working beautifully, but I need to add in some additional columns that also link back to TblStaff.User_Code My design currently looks like this, the highlighted fields are the ones I need to link in my query:
What I need to do is add 2 additional columns, 1 for HoYEmail and one for AsstHoYEmail using txtYearTutor linked by User_Code as TblStaff.SchoolEmailAddress AS HoYEmail and the AsstYearTutor linked by User_Code as TblStaff.SchoolEmailAddress AS AsstHoYEmail all grouped by TblPupilManagementPupils.txtSchoolID
Producing something like this:
Any tips gratefully received.

After a bit of research, I ended up completely re-writing this query to get it to work using correlation names for the staff table.
SELECT TblSchoolManagementForms.txtForm, TblPupilManagementPupils.txtSchoolID, TblPupilManagementPupils.txtSurname, TblPupilManagementPupils.txtForename,
TblStaff.SchoolEmailAddress AS TutorEmail, TblStaff_1.SchoolEmailAddress AS HoYEmail, TblStaff_2.SchoolEmailAddress AS AsstHoYEmail
FROM TblStaff INNER JOIN
TblPupilManagementPupils INNER JOIN
TblSchoolManagementForms ON TblPupilManagementPupils.txtForm = TblSchoolManagementForms.txtForm ON
TblStaff.User_Code = TblSchoolManagementForms.txtFormTutor INNER JOIN
TblSchoolManagementYears ON TblPupilManagementPupils.intNCYear = TblSchoolManagementYears.intNCYear INNER JOIN
TblStaff AS TblStaff_1 ON TblSchoolManagementYears.txtYearTutor = TblStaff_1.User_Code INNER JOIN
TblStaff AS TblStaff_2 ON TblSchoolManagementYears.txtAsstYearTutor = TblStaff_2.User_Code
WHERE (TblSchoolManagementYears.intNCYear > 6) AND (TblPupilManagementPupils.intSystemStatus = 1)
UNION
SELECT TblSchoolManagementForms.txtForm, TblPupilManagementPupils.txtSchoolID, TblPupilManagementPupils.txtSurname, TblPupilManagementPupils.txtForename,
TblStaff.SchoolEmailAddress AS TutorEmail, TblStaff_1.SchoolEmailAddress AS HoYEmail, TblStaff_2.SchoolEmailAddress AS AsstHoYEmail
FROM TblStaff INNER JOIN
TblPupilManagementPupils INNER JOIN
TblSchoolManagementForms ON TblPupilManagementPupils.txtForm = TblSchoolManagementForms.txtForm ON
TblStaff.User_Code = TblSchoolManagementForms.txtAsstFormTutor INNER JOIN
TblSchoolManagementYears ON TblPupilManagementPupils.intNCYear = TblSchoolManagementYears.intNCYear INNER JOIN
TblStaff AS TblStaff_1 ON TblSchoolManagementYears.txtYearTutor = TblStaff_1.User_Code INNER JOIN
TblStaff AS TblStaff_2 ON TblSchoolManagementYears.txtAsstYearTutor = TblStaff_2.User_Code
WHERE (TblSchoolManagementYears.intNCYear > 6) AND (TblPupilManagementPupils.intSystemStatus = 1)

Related

PostgreSQL Inner Join Where Get IDs of 3 Products

I have these 5 tables which is sale_order directly connected to sale_order_line that has the products of the order of course which is connected to product_product that is connected to product_template where a table called mrp_bom can connect to product template and a table connected to it which is bom_line. I am trying to Output the products that contain the word 836g
Here is what I have so far:
Select so.name,
pt.name,
sol.name
From sale_order so
Inner Join sale_order_line sol
On so.id = sol.order_id
Inner Join product_template pt
On sol.product_id = pt.id
Inner Join mrp_bom bom
On pt.id = bom.product_tmpl_id
Inner Join mrp_bom_line boml
On bom.id = boml.bom_id
Where boml.product_id = (Select id From product_template Where name Like '%836g%'
Order By so.name
This code outputs an error because I have 3 items with 836g. I tried changing the = in the condition into IN so it will grab all the ids it will return. But still it's giving me an error. This is the best I have so far, I have tried so many times, but I can't figure it out.
I have the feeling that something along these lines is what you actually want:
SELECT so.name,
pt.name,
sol.name
FROM sale_order so
INNER JOIN sale_order_line sol
ON so.id = sol.order_id
INNER JOIN product_template pt
ON sol.product_id = pt.id
INNER JOIN mrp_bom bom
ON pt.id = bom.product_tmpl_id
INNER JOIN mrp_bom_line boml
ON bom.id = boml.bom_id
WHERE pt.name LIKE '%836g%' -- just add a WHERE condition directly in your query
ORDER BY so.name
OMG! I just had the answer. I don't think this will help anyone but i'll post the answer i have
SELECT so.name,
pt.name PT,
sol.name SOL,
(Select pp1.name_template From product_product pp1 Where boml.product_id = pp1.id) BOML,
boml.product_id
FROM sale_order so
INNER JOIN sale_order_line sol
ON so.id = sol.order_id
INNER JOIN product_template pt
ON sol.product_id = pt.id
INNER JOIN mrp_bom bom
ON pt.id = bom.product_tmpl_id
INNER JOIN mrp_bom_line boml
ON bom.id = boml.bom_id
WHERE (Select pp1.name_template From product_product pp1 Where boml.product_id = pp1.id) LIKE '%836g%'
ORDER BY so.name
Thank you all for the effort of helping me! Great community we got here! :D

Why does not adding distinct in this query produce duplicate rows?

This query was taken from a Rails application log...I'm trying to edit a massive postgresql statement I didn't write....If I don't add a distinct keyword after the SELECT, 2 duplicate rows appear for each braintree account. Why is this and is there another way to avoid having to use the distinct to avoid duplicates?
EDIT: I understand what distinct is supposed to do, the reason I'm asking is that it doesn't generate duplicates for other toy lines. By other toy lines, this query is building a "table" for a particular toy id (this specific example toys.id = 12). How do I figure out where the duplicate rows are being generated?
SELECT accounts.braintree_account_id as braintree_account_id,
accounts.braintree_account_id as braintree_account_id, format('%s %s', addresses.first_name,
addresses.last_name) as shipping_address_full_name,
users.email as email, addresses.line_1 as shipping_address_line_1,
addresses.line_2 as shipping_address_line_2, addresses.city as
shipping_address_city, addresses.state as shipping_address_state,
addresses.zip as shipping_address_zip_code, addresses.country
as shipping_address_country, CASE WHEN xy_shirt IS NULL THEN '' ELSE xy_shirt END, plans.name as plan_name, toys.sku as sku, to_char(accounts.created_at, 'MM/DD/YYYY HH24:MM:SS') as
account_created_at,
to_char(accounts.next_assessment_at, 'MM/DD/YYYY HH24:MM:SS') as account_next_assessment_at,
accounts.account_status as account_status FROM \"accounts\" INNER JOIN \"addresses\" ON
\"addresses\".\"id\" = \"accounts\".\"shipping_address_id\" AND \"addresses\".\"type\" IN
('ShippingAddress') LEFT OUTER JOIN shipping_methods ON
shipping_methods.account_id = accounts.id LEFT OUTER JOIN plans ON
accounts.plan_id = plans.id
LEFT OUTER JOIN users ON
accounts.user_id = users.id LEFT OUTER JOIN toys ON plans.toy_id = toys.id
LEFT OUTER JOIN account_variations ON accounts.id =
account_variations.account_id LEFT OUTER JOIN variations ON
account_variations.variation_id = variations.id
LEFT OUTER JOIN
choice_value_variations ON variations.id =
choice_value_variations.variation_id
LEFT OUTER JOIN choice_values ON
choice_value_variations.choice_value_id = choice_values.id LEFT OUTER
JOIN choice_types ON choice_values.choice_type_id = choice_types.id
LEFT
OUTER JOIN choice_type_toys ON choice_type_toys.toy_id = toys.id
AND choice_type_toys.choice_type_id = choice_types.id
LEFT OUTER JOIN
(SELECT * FROM crosstab('SELECT accounts.id, choice_types.id,
choice_values.presentation FROM accounts\n
LEFT JOIN account_variations ON
accounts.id=account_variations.account_id\n
LEFT JOIN variations ON account_variations.variation_id=variations.id\n
LEFT JOIN choice_value_variations ON
variations.id=choice_value_variations.variation_id\n
LEFT JOIN choice_values ON
choice_value_variations.choice_value_id=choice_values.id\n
LEFT JOIN choice_types ON choice_values.choice_type_id=choice_types.id
ORDER BY 1,2',\n 'select distinct choice_types.id
from choice_types JOIN choice_values ON choice_values.choice_type_id =
choice_types.id JOIN choice_value_variations ON
choice_value_variations.choice_value_id = choice_values.id JOIN
variations ON choice_value_variations.variation_id = variations.id JOIN choice_type_toys ON choice_type_toys.choice_type_id = choice_types.id JOIN toys ON toys.id = choice_type_toys.toy_id
where toys.id=12 ORDER
BY choice_types.id ASC')\n
AS (account_id int, xy_shirt
VARCHAR)) account_variation_view\n ON
accounts.id=account_variation_view.account_id WHERE
\"accounts\".\"account_status\" = 'active' AND
\"addresses\".\"flagged_invalid_at\" IS NULL AND \"toys\".\"id\" = 12
AND (NOT EXISTS (SELECT \"account_skipped_months\".* FROM
\"account_skipped_months\" WHERE
\"account_skipped_months\".\"month_year\" = 'JUL2016' AND
(account_skipped_months.account_id = accounts.id)))"
The purpose of using DISTINCT in a SELECT statement is to eliminate duplicate rows.

sql, group a query with no aggregations and multiple tables

I need to group the query below by dda.LA and need to display all the columns listed in the select but almost none of them are aggregated. i don't know what the syntax to get around this is and i can not find a post that shows this syntax (most examples only have one table, two at tops).
Select dda.a,
dda.b,
dda.c,
dda.d,
dda.e,
dda.f,
dda.g,
dda.h,
dda.i,
dda.j,
dda.k,
dda.l,
dda.m,
dda.n,
dda.o,
dda.p,
dda.r,
dda.u,
dda.LA,
dd.aa,
coalesce(apn.apn,Pt.z) as abc,
coalesce(apn.v,Pt.y) as def,
'RFN' RowFocusIndicator ,
'SRI' SelectRowIndicator ,
'Y' Expanded ,
Convert(Int, Null) SortColumn
From dda (NoLock)
Inner Join dd (NoLock) On dda.d = dd.q and dda.e = dd.e
Left Outer Join apn (nolock) on dda.r = apn.r
Left Outer Join Pt (nolock) on dda.s = Pt.t
Where 1 = 1
And dda.u = (Select Min(c.w)
From c (NoLock)
Where c.x = dda.s)
Thanks!
Just add this to any column that you want to aggregate by:
AggregatedColumnName = Aggregation(fieldToAggregate) Over (Partition By dda.LA)
ex.
aCount = Count(dda.a) Over (Partition By dda.LA)

Check foreign keys

I want to extend my query for delete and update rule, but I just can not figure what column in what systable that is in.
My query so far:
select oct.name FKNeve,oft.name TAmit,ofc.name MAmit,ort.name TAmihez,orc.name MAmihez
from sysforeignkeys sfk
inner join sysobjects oct on sfk.constid = oct.id
inner join sysobjects oft on sfk.fkeyid = oft.id
inner join syscolumns ofc on sfk.fkey = ofc.colid and sfk.fkeyid = ofc.id
inner join sysobjects ort on sfk.rkeyid = ort.id
inner join syscolumns orc on sfk.rkey = orc.colid and sfk.rkeyid = orc.id
Oh and MSDE.
Use the OBJECTPROPERTY function (with 'CnstIsDeleteCascade'/'CnstIsUpdateCascade' as the second argument).

Eliminating NULL rows in TSQL query [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
How to eliminate NULL fields in TSQL
I am using SSMS 2008 R2 and am developing a TSQL query. I want just 1 record / profile_name. Because some of these values are NULL, I am currently doing LEFT JOINS on most of the tables. But the problem with the LEFT JOINs is that now I get > 1 record for some profile_names!
But if I change this to INNER JOINs then some profile_names are excluded entirely because they have NULL values for these columns. How do I limit the query result to just one record / profile_name regardless of NULL values? And if there are non-NULL values then I want it to choose the record with non-NULL values. Here is initial query:
select distinct
gp.group_profile_id,
gp.profile_name,
gp.license_number,
gp.is_accepting,
case when gp.is_accepting = 1 then 'Yes'
when gp.is_accepting = 0 then 'No '
end as is_accepting_placement,
mo.profile_name as managing_office,
regions.[region_description] as region,
pv.vendor_name,
pv.id as vendor_id,
at.description as applicant_type,
dbo.GetGroupAddress(gp.group_profile_id, null, 0) as [Office Address],
gsv.status_description
from group_profile gp With (NoLock)
inner join group_profile_type gpt With (NoLock) on gp.group_profile_type_id = gpt.group_profile_type_id and gpt.type_code = 'FOSTERHOME' and gp.agency_id = #agency_id and gp.is_deleted = 0
inner join group_profile mo With (NoLock) on gp.managing_office_id = mo.group_profile_id
left outer join payor_vendor pv With (NoLock) on gp.payor_vendor_id = pv.payor_vendor_id
left outer join applicant_type at With (NoLock) on gp.applicant_type_id = at.applicant_type_id and at.is_foster_home = 1
inner join group_status_view gsv With (NoLock) on gp.group_profile_id = gsv.group_profile_id and gsv.status_value = 'OPEN' and gsv.effective_date =
(Select max(b.effective_date) from group_status_view b With (NoLock)
where gp.group_profile_id = b.group_profile_id)
left outer join regions With (NoLock) on isnull(mo.regions_id, gp.regions_id) = regions.regions_id
left join enrollment en on en.group_profile_id = gp.group_profile_id
join event_log el on el.event_log_id = en.event_log_id
left join people client on client.people_id = el.people_id
As you can see, the results of the above query is 1 row / profile_name:
group_profile_id profile_name license_number is_accepting is_accepting_placement managing_office region vendor_name vendor_id applicant_type Office Address status_description Cert Date2
But now watch what happens when I add in 2 LEFT JOINs and 1 additional column:
select distinct
gp.group_profile_id,
gp.profile_name,
gp.license_number,
gp.is_accepting,
case when gp.is_accepting = 1 then 'Yes'
when gp.is_accepting = 0 then 'No '
end as is_accepting_placement,
mo.profile_name as managing_office,
regions.[region_description] as region,
pv.vendor_name,
pv.id as vendor_id,
at.description as applicant_type,
dbo.GetGroupAddress(gp.group_profile_id, null, 0) as [Office Address],
gsv.status_description,
ri.[description] as race
from group_profile gp With (NoLock)
inner join group_profile_type gpt With (NoLock) on gp.group_profile_type_id = gpt.group_profile_type_id and gpt.type_code = 'FOSTERHOME' and gp.agency_id = #agency_id and gp.is_deleted = 0
inner join group_profile mo With (NoLock) on gp.managing_office_id = mo.group_profile_id
left outer join payor_vendor pv With (NoLock) on gp.payor_vendor_id = pv.payor_vendor_id
left outer join applicant_type at With (NoLock) on gp.applicant_type_id = at.applicant_type_id and at.is_foster_home = 1
inner join group_status_view gsv With (NoLock) on gp.group_profile_id = gsv.group_profile_id and gsv.status_value = 'OPEN' and gsv.effective_date =
(Select max(b.effective_date) from group_status_view b With (NoLock)
where gp.group_profile_id = b.group_profile_id)
left outer join regions With (NoLock) on isnull(mo.regions_id, gp.regions_id) = regions.regions_id
left join enrollment en on en.group_profile_id = gp.group_profile_id
join event_log el on el.event_log_id = en.event_log_id
left join people client on client.people_id = el.people_id
left join race With (NoLock) on el.people_id = race.people_id
left join race_info ri with (nolock) on ri.race_info_id = race.race_info_id
The above query results in all of the same profile_names, but some with NULL race values:
group_profile_id profile_name license_number is_accepting is_accepting_placement managing_office region vendor_name vendor_id applicant_type Office Address status_description Cert Date2 race
Unfortunately it complicates matters that I need to join in 2 additional tables for this one additional field value (race). If I simply change the last two LEFT JOINs above to INNER JOINs then I eliminate the NULL rows above. But I also eliminate some of the profile_names:
group_profile_id profile_name license_number is_accepting is_accepting_placement managing_office region vendor_name vendor_id applicant_type Office Address status_description Cert Date2 race
Hopefully I have provided all of the details that you need for this question.
Not the most elegant solution, but one that will work:
select [stuff]
from group_profile gp With (NoLock)
inner join group_profile_type gpt With (NoLock) on gp.group_profile_type_id = gpt.group_profile_type_id and gpt.type_code = 'FOSTERHOME' and gp.agency_id = #agency_id and gp.is_deleted = 0
inner join group_profile mo With (NoLock) on gp.managing_office_id = mo.group_profile_id
join payor_vendor pv on ISNULL(gp.payor_vendor_id, 'THISVALUEWILLNEVEROCCUR') = ISNULL(pv.payor_vendor_id, 'THISVALUEWILLNEVEROCCUR')
...etc...
Biggest issue with what I posted is that you'll be doing a whole lot of table scans.