Comparing Query Result With Table and Retrieve Specific Field - sql

My Query
SELECT
stoMast.sStockistCode,
stoMast.sStateName,
stoMast.sDivision,
stateMap.sRMCode
FROM
tblRSM_State_Mapping stateMap
INNER JOIN
tblStockistMaster stoMast ON
stateMap.sStateName = stoMast.sStateName
WHERE
stateMap.sRMCode = 'MCNE04001'
and
stoMast.sDivision = 'CIDIS'
except
select
sStockistCode,
sStateName,
sDivision,
sRMCode
From
tblEntry
Again I would like to compare the query result columns
sStockistCode
sStateName
sDivision
with tblStockistMaster with the same fields
sStockistCode
sStateName
sDivision
and retrieve the STOCKIST NAME.
Don't know how to compare the above query result with the table.

Maybe you can use following SQL code used with CTE expression
;with cte as (
SELECT
stoMast.sStockistCode,
stoMast.sStateName,
stoMast.sDivision,
stateMap.sRMCode
FROM
tblRSM_State_Mapping stateMap
INNER JOIN
tblStockistMaster stoMast ON
stateMap.sStateName = stoMast.sStateName
WHERE
stateMap.sRMCode = 'MCNE04001'
and
stoMast.sDivision = 'CIDIS'
except
select
sStockistCode,
sStateName,
sDivision,
sRMCode
From
tblEntry
)
select
cte.*,
sm.sStockistName
from cte
left join tblStockistMaster as sm
on sm.sStockistCode = cte.sStockistCode and
sm.sStateName = cte.sStateName and
sm.sDivision = cte.sDivision

-- I retrieve the stockist Name
SELECT
stoMast.sStockistName,
FROM
tblRSM_State_Mapping stateMap
INNER JOIN
tblStockistMaster stoMast
ON stateMap.sStateName = stoMast.sStateName
-- I'm joining table entry If I can match
LEFT JOIN
tblEntry tbl
on tbl.sStockistCode = stoMast.sStockistName
AND tbl.sStateName = stoMast.sStateName
AND tbl.sDivision = stoMast.sDivision
AND tbl.sRMCode = stateMap.sRMCode
WHERE
stateMap.sRMCode = 'MCNE04001'
and stoMast.sDivision = 'CIDIS'
-- And The the exept thing, I don't want that got a match with the tableentry
AND COALESCE(tbl.sStockistCode, tbl.sStateName, tbl.sDivision, tbl.sRMCode) is null
I expect it is what you wanted to get. On another way please help us understand wht you come from (tables and idea of what data can be in) and the result you want. Will be easier to create a query.

Related

SQL Server Loop Over Records

I have a view vwDocumentLinks with data as shown below:
I have another table RiskTypes with data as below.
The link between the table & viewis : Idx25 = Risk Type and LinkDocNo = DocumentType. What I am trying to achieve is to get DocumentType in RiskTypes that's not in the view vwDocumentLinks foreach BaseValue and where Idx25 = RiskType. An example using a single BaseValue will be:
SELECT * FROM RiskTypeDocuments WHERE RiskType = 'BUSINESS LIMITED COMPANY' AND DocumentType NOT IN (SELECT LINKDOCNO FROM DBO.VWLINKS WHERE BaseValue = '00007573-1637-4B8E-9374-730AF58BCFB6')
I tried the below query and it's not working as expected. Any help will be greatly appreciated. I am a newbie in SQL
SELECT dbo.RiskTypeDocuments.DocumentType,
dbo.RiskTypeDocuments.RiskType,
dbo.vwLinks.BaseValue AS Document
FROM dbo.vwLinks LEFT OUTER JOIN
dbo.RiskTypeDocuments ON dbo.vwLinks.LinkDocNo =
dbo.RiskTypeDocuments.DocumentType AND dbo.vwLinks.Idx25 =
dbo.RiskTypeDocuments.RiskType
WHERE dbo.RiskTypeDocuments.DocumentType IS NOT NULL
ORDER BY Document
NB: I can't change the schema. I can only create views from the existing tables.
Sample Data from the two datasets: vwDocumentLinks & RiskTypeDocuments
SELECT a.DocumentType,
a.RiskType,
b.BaseValue AS Document
FROM dbo.RiskTypeDocuments as a
INNER JOIN (Select distinct Idx25, BaseValue from vwDocumentLinks) as b on b.Idx25 = a.RiskType
where a.DocumentType not in (Select LINKDOCNO from vwDocumentLinks as c where c.basevalue = b.BaseValue )
I think what you are looking for is NOT EXISTS. It takes a little to get your head around, but the idea is to have what is called a correlated subquery. The subquery is joined to the main query, hence the term correlated.
SELECT *
FROM RiskTypeDocuments
WHERE NOT EXISTS (
SELECT 1 FROM vwDocumentLinks
WHERE RiskTypeDocuments.RiskType = vwDocumentLinks.idx25
AND RiskTypeDocuments.DocumentType = vwDocumentLinks.LinkDocNo
)
If you want to retrieve the records which don't exist in the view then
Try like this
SELECT d.DocumentType,
d.RiskType,
v.BaseValue
FROM dbo.vwLinks AS v
OUTER JOIN dbo.RiskTypeDocuments d ON v.LinkDocNo = d.DocumentType AND v.vwLinks.Idx25 =d.RiskType
WHERE v.BaseValue IS NULL
ORDER BY DocumentType

Duplicate rows while multiplying two columns of two different tables using joins

I have these following tables
Question_Segment_Master
Question_Set_Details
While I am joining these two tables I am getting duplicate rows..
Please view fiddle,where I posted those twos schema and it's data..
http://sqlfiddle.com/#!18/4c84f/10
This is my expected OP
You need to get the question_marks of each segment. Also, you should JOIN using the branch_id, test_id, subject_code_id along with the segment_id.
Using JOIN and then take Distinct values
SELECT DISTINCT qsm.segment_id, segment_name, segment_description
, must_attend_question AS tot_attented_question, total_question AS tot_questions
, (qsd.question_marks * must_attend_question) AS tot_marks
, '' AS marks_obtain
FROM dbo.Question_Segment_Master AS qsm
INNER JOIN dbo.Question_Set_Details AS qsd
ON (qsd.branch_id = qsm.branch_id AND qsd.test_id = qsm.test_id
AND qsd.segment_id = qsm.segment_id AND qsd.subject_code_id = qsm.subject_code_id)
WHERE qsm.subject_code_id = 1 and qsm.test_id = 1 and qsm.branch_id = 15;
Demo
You were missing the segment_id in your join clause
SELECT DISTINCT
qsm.segment_id,
qsm.segment_name,
qsm.segment_description,
qsm.must_attend_question tot_attented_question,
qsm.total_question tot_questions,
(qsd.question_marks * must_attend_question) tot_marks,
'' AS marks_obtain
FROM dbo.question_segment_master qsm
INNER JOIN dbo.question_set_details qsd on
qsd.test_id = qsm.test_id
and qsd.segment_id = qsm.segment_id
WHERE qsm.test_id=1
AND qsm.branch_id = 15
AND qsm.subject_code_id =1 AND qsd.question_set_id = 1

Only return value that matches the ID on table 1

I have tried all possible joins and sub-queries but I cant get the data to only return one value from table 2 that exactly matches the vendor ID. If I dont have the address included in the query, I get one hit for the vendor ID. How can I make it so that when I add the address, I only want the one vendor that I get prior to adding the address.
The vendor from table one must be VEN-CLASS IS NOT NULL.
This was my last attempt using subquery:
SELECT DISTINCT APVENMAST.VENDOR_GROUP,
APVENMAST.VENDOR,
APVENMAST.VENDOR_VNAME,
APVENMAST.VENDOR_CONTCT,
APVENMAST.TAX_ID,
Subquery.ADDR1
FROM (TEST.dbo.APVENMAST APVENMAST
INNER JOIN
(SELECT APVENADDR.ADDR1,
APVENADDR.VENDOR_GROUP,
APVENADDR.VENDOR,
APVENMAST.VEN_CLASS
FROM TEST.dbo.APVENADDR APVENADDR
INNER JOIN TEST.dbo.APVENMAST APVENMAST
ON (APVENADDR.VENDOR_GROUP = APVENMAST.VENDOR_GROUP)
AND (APVENADDR.VENDOR = APVENMAST.VENDOR)
WHERE (APVENMAST.VEN_CLASS IS NOT NULL)) Subquery
ON (APVENMAST.VENDOR_GROUP = Subquery.VENDOR_GROUP)
AND (APVENMAST.VENDOR = Subquery.VENDOR))
INNER JOIN TEST.dbo.APVENLOC APVENLOC
ON (APVENMAST.VENDOR_GROUP = APVENLOC.VENDOR_GROUP)
AND (APVENMAST.VENDOR = APVENLOC.VENDOR)
WHERE (APVENMAST.VEN_CLASS IS NOT NULL)
Try this:
SELECT APVENMAST.VENDOR_GROUP
, APVENMAST.VENDOR
, APVENMAST.VENDOR_VNAME
, APVENMAST.VENDOR_CONTCT
, APVENMAST.TAX_ID
, APVENADDR.ADDR1
FROM TEST.dbo.APVENMAST APVENMAST
INNER JOIN (
select VENDOR_GROUP, VENDOR, ADDR1
, row_number() over (partition by VENDOR_GROUP, VENDOR order by ADDR1) r
from TEST.dbo.APVENADDR
) APVENADDR
ON APVENADDR.VENDOR_GROUP = APVENMAST.VENDOR_GROUP
AND APVENADDR.VENDOR = APVENMAST.VENDOR
AND APVENADDR.r = 1
--do you need this table; you're not using it...
--INNER JOIN TEST.dbo.APVENLOC APVENLOC
--ON APVENMAST.VENDOR_GROUP = APVENLOC.VENDOR_GROUP
--AND APVENMAST.VENDOR = APVENLOC.VENDOR
WHERE APVENMAST.VEN_CLASS IS NOT NULL
--if the above inner join was to filter results, you can do this instead:
and exists (
select top 1 1
from TEST.dbo.APVENLOC APVENLOC
ON APVENMAST.VENDOR_GROUP = APVENLOC.VENDOR_GROUP
AND APVENMAST.VENDOR = APVENLOC.VENDOR
)
I found another column in the APVENLOC table that I can filter on to get the unique vendor. Turns out if the vendor address is for the main office, the vendor location is set blank.
Easier than I thought it would be!
SELECT DISTINCT APVENMAST.VENDOR_GROUP,
APVENMAST.VENDOR,
APVENMAST.VENDOR_VNAME,
APVENADDR.ADDR1,
APVENMAST.VENDOR_SNAME,
APVENADDR.LOCATION_CODE,
APVENMAST.VEN_CLASS
FROM TEST.dbo.APVENMAST APVENMAST
INNER JOIN TEST.dbo.APVENADDR APVENADDR
ON (APVENMAST.VENDOR_GROUP = APVENADDR.VENDOR_GROUP)
AND (APVENMAST.VENDOR = APVENADDR.VENDOR)
WHERE (APVENADDR.LOCATION_CODE = ' ')
Shaji

Confused in join query in SQL

The following works:
SELECT IBAD.TRM_CODE, IBAD.IPABD_CUR_QTY, BM.BOQ_ITEM_NO,
IBAD.BCI_CODE, BCI.BOQ_CODE
FROM IPA_BOQ_ABSTRCT_DTL IBAD,
BOQ_CONFIG_INF BCI,BOQ_MST BM
WHERE BM.BOQ_CODE = BCI.BOQ_CODE
AND BCI.BCI_CODE = IBAD.BCI_CODE
AND BCI.STATUS = 'Y'
AND BM.STATUS = 'Y'
order by boq_item_no;
Results:
But after joining many tables with that query, the result is confusing:
SELECT (SELECT CMN_NAME
FROM CMN_MST
WHERE CMN_CODE= BRI.CMN_RLTY_MTRL) MTRL,
RRI.RRI_RLTY_RATE AS RATE,
I.BOQ_ITEM_NO,
(TRIM(TO_CHAR(IBAD.IPABD_CUR_QTY,
'9999999999999999999999999999990.999'))) AS IPABD_CUR_QTY,
TRIM(TO_CHAR(BRI.BRI_WT_FACTOR,
'9999999999999999999999999999990.999')) AS WT,
TRIM(TO_CHAR((IBAD.IPABD_CUR_QTY*BRI.BRI_WT_FACTOR),
'9999999999999999999999990.999')) AS RLTY_QTY,
(TRIM(TO_CHAR((IBAD.IPABD_CUR_QTY*BRI.BRI_WT_FACTOR*RRI.RRI_RLTY_RATE),
'9999999999999999999999990.99'))) AS TOT_AMT,
I.TRM_CODE AS TRM
FROM
(SELECT * FROM ipa_boq_abstrct_dtl) IBAD
INNER JOIN
(SELECT * FROM BOQ_RLTY_INF) BRI
ON IBAD.BCI_CODE = BRI.BCI_CODE
INNER JOIN
(SELECT * FROM RLTY_RATE_INF) RRI
ON BRI.CMN_RLTY_MTRL = RRI.CMN_RLTY_MTRL
INNER JOIN
( SELECT IBAD.TRM_CODE, IBAD.IPABD_CUR_QTY,
BM.BOQ_ITEM_NO, IBAD.BCI_CODE, BCI.BOQ_CODE
FROM IPA_BOQ_ABSTRCT_DTL IBAD,
BOQ_CONFIG_INF BCI,BOQ_MST BM
WHERE
BM.BOQ_CODE = BCI.BOQ_CODE
AND BCI.BCI_CODE = IBAD.BCI_CODE
and BCI.status = 'Y'
and bm.status = 'Y') I
ON BRI.BCI_CODE = I.BCI_CODE
AND I.TRM_CODE = BRI.TRM_CODE
AND BRI.TRM_CODE =4
group by BRI.CMN_RLTY_MTRL, RRI.RRI_RLTY_RATE, I.BOQ_ITEM_NO,
IBAD.IPABD_CUR_QTY, BRI.BRI_WT_FACTOR, I.TRM_CODE, I.bci_code
order by BRI.CMN_RLTY_MTRL
Results:
TRM should be 11 instead of 4 in the first row.
you getting 4 because you use
AND BRI.TRM_CODE =4
if you remove this criter you can get true result
In your first query, both of the rows you've highlighted have BCI_CODE=1866.
In the second query, you are joining that result set with a number of others (which come from the same tables, which seems odd). In particular, you are joining from the subquery to another table using BCI_CODE, and from there to (SELECT * FROM ipa_boq_abstrct_dtl) IBAD. Since both of the rows from the subquery have the same BCI_CODE, they will join to the same rows in the other tables.
The quantity that you are actually displaying in the second query is from (SELECT * FROM ipa_boq_abstrct_dtl) IBAD, not from the other subquery.
Is the problem simply that you mean to select I.IPABD_CUR_QTY instead of IBAD.IPABD_CUR_QTY?
You might find this clearer if you did not reuse the same aliases for tables at multiple points in the query.

Column is invalid in the ORDER BY clause because it is not contained in either an aggregate function or the GROUP BY clause

Ok here's my View (vw_LiftEquip)
SELECT dbo.tbl_equip_swl_unit.unit_id,
dbo.tbl_equip_swl_unit.unit_name,
dbo.tbl_equip_swl_unit.archived,
dbo.tbl_categories.category_id,
dbo.tbl_categories.categoryName,
dbo.tbl_categories.parentCategory,
dbo.tbl_categories.sub_category,
dbo.tbl_categories.desc_category,
dbo.tbl_categories.description,
dbo.tbl_categories.miscellaneous,
dbo.tbl_categories.category_archived,
dbo.tbl_equip_swl_unit.unit_name AS Expr1,
dbo.tbl_categories.categoryName AS Expr2,
dbo.tbl_categories.description AS Expr3,
dbo.tbl_equip_depts.dept_name,
dbo.tbl_equip_man.man_name,
dbo.tbl_Lifting_Gear.e_defects AS Expr7,
dbo.tbl_Lifting_Gear.e_defects_desc AS Expr8,
dbo.tbl_Lifting_Gear.e_defects_date AS Expr9,
dbo.tbl_equipment.equipment_id,
dbo.tbl_equipment.e_contract_no,
dbo.tbl_equipment.slID,
dbo.tbl_equipment.e_entered_by,
dbo.tbl_equipment.e_serial,
dbo.tbl_equipment.e_model,
dbo.tbl_equipment.e_description,
dbo.tbl_equipment.e_location_id,
dbo.tbl_equipment.e_owner_id,
dbo.tbl_equipment.e_department_id,
dbo.tbl_equipment.e_manafacture_id,
dbo.tbl_equipment.e_manDate1,
dbo.tbl_equipment.e_manDate2,
dbo.tbl_equipment.e_manDate3,
dbo.tbl_equipment.e_dimensions,
dbo.tbl_equipment.e_test_no,
dbo.tbl_equipment.e_firstDate1,
dbo.tbl_equipment.e_firstDate2,
dbo.tbl_equipment.e_firstDate3,
dbo.tbl_equipment.e_prevDate1,
dbo.tbl_equipment.e_prevDate2,
dbo.tbl_equipment.e_prevDate3,
dbo.tbl_equipment.e_insp_frequency,
dbo.tbl_equipment.e_swl,
dbo.tbl_equipment.e_swl_unit_id,
dbo.tbl_equipment.e_swl_notes,
dbo.tbl_equipment.e_cat_id,
dbo.tbl_equipment.e_sub_id,
dbo.tbl_equipment.e_parent_id,
dbo.tbl_equipment.e_last_inspector,
dbo.tbl_equipment.e_last_company,
dbo.tbl_equipment.e_deleted AS Expr11,
dbo.tbl_equipment.e_deleted_desc AS Expr12,
dbo.tbl_equipment.e_deleted_date AS Expr13,
dbo.tbl_equipment.e_deleted_insp AS Expr14,
dbo.tbl_Lifting_Gear.e_defects_action AS Expr15,
dbo.tbl_equipment.e_rig_location,
dbo.tbl_Lifting_Gear.e_add_type AS Expr17,
dbo.tbl_Lifting_Gear.con_id,
dbo.tbl_Lifting_Gear.lifting_date,
dbo.tbl_Lifting_Gear.lifting_ref_no,
dbo.tbl_Lifting_Gear.e_id,
dbo.tbl_Lifting_Gear.inspector_id,
dbo.tbl_Lifting_Gear.lift_testCert,
dbo.tbl_Lifting_Gear.lift_rig_location,
dbo.tbl_Lifting_Gear.inspected,
dbo.tbl_Lifting_Gear.lifting_through,
dbo.tbl_Lifting_Gear.liftingNDT,
dbo.tbl_Lifting_Gear.liftingTest,
dbo.tbl_Lifting_Gear.e_defects,
dbo.tbl_Lifting_Gear.e_defects_desc,
dbo.tbl_Lifting_Gear.e_defects_date,
dbo.tbl_Lifting_Gear.e_defects_action,
dbo.tbl_Lifting_Gear.lift_department_id,
dbo.tbl_Lifting_Gear.lifting_loc
FROM dbo.tbl_equipment
INNER JOIN dbo.tbl_equip_swl_unit
ON dbo.tbl_equipment.e_swl_unit_id = dbo.tbl_equip_swl_unit.unit_id
INNER JOIN dbo.tbl_categories
ON dbo.tbl_equipment.e_cat_id = dbo.tbl_categories.category_id
INNER JOIN dbo.tbl_equip_depts
ON dbo.tbl_equipment.e_department_id = dbo.tbl_equip_depts.dept_id
INNER JOIN dbo.tbl_equip_man
ON dbo.tbl_equipment.e_manafacture_id = dbo.tbl_equip_man.man_id
INNER JOIN dbo.vwSubCategory
ON dbo.tbl_equipment.e_sub_id = dbo.vwSubCategory.category_id
INNER JOIN dbo.vwDescCategory
ON dbo.tbl_equipment.e_cat_id = dbo.vwDescCategory.category_id
INNER JOIN dbo.tbl_Lifting_Gear
ON dbo.tbl_equipment.equipment_id = dbo.tbl_Lifting_Gear.e_id
And here's the select statement with subquery that I am using:
SELECT *
FROM vw_LiftEquip
WHERE lifting_loc = ? AND
con_id = ? AND
EXPR11 =
'N'(
SELECT MAX(lifting_date) AS maxLift
FROM vw_LiftEquip
WHERE e_id = equipment_id
)
ORDER BY lifting_ref_no,
category_id,
e_swl,
e_serial
I get the error :
Column "vw_LiftEquip.category_id" is invalid in the ORDER BY clause because it is not contained in either an aggregate function or the GROUP BY clause.
Can't see why its returning that error, this is admittedly the first time I've ran a subquery on such a complex view, and I am a bit lost, thanks in advance for any help. I have looked through the similar posts and can find no answers to this one, sorry if I am just being dumb.
You are missing AND between EXPR11 = 'N' and (SELECT MAX(...
Otherwise, it looks OK. MAX without GROUP BY is allowed if you have no other columns in the SELECT
Update: #hvd also noted that you have nothing to compare to MAX(lifting_date). See comment
Update 2,
SELECT *
FROM vw_LiftEquip v1
CROSS JOIN
(
SELECT MAX(lifting_date) AS maxLift
FROM vw_LiftEquip
WHERE e_id = equipment_id
) v2
WHERE v1.lifting_loc = ? AND
v1.con_id = ? AND
v1.EXPR11 = 'N'
ORDER BY v1.lifting_ref_no,
v1.category_id,
v1.e_swl,
v1.e_serial