SELECT from SELECT in SQL - sql

I'm working in small food depot where we preparing deliveries for small shops. We using WMS to get our work done. For some reasons i need to get some data from database using SQL builder in system. So the case is.
To get information to which store particular product has been despatched I'm using this query:
select cd.cage_nbr, cd.units_of_product, pk.to_store
from cage_dtl cd
inner join item_master im on im.sku_id=cd.sku_id
INNER JOIN pkt_hdr pk ON pk.pkt_ctrl_nbr=cd.pkt_ctrl_nbr
where im.barcode = '105683004'
and cd.open_cage_batch = 31102014
To see list of stores and quantities of product allocated by our customer i'm using this query:
select sd.to_store, sd.alloc_qty, sd.alloc_batch, im.size_desc
from store_distro sd
inner join item_master im on im.sku_id=sd.sku_id
where im.barcode = '105683004'
and sd.alloc_batch = 31102014
But i need a SQL to show me any stores to which product has not been despatched.
I will appreaciate any help
Thanks

You can probably try doing a LEFT JOIN for your first query and check for NULL. Something like
select cd.cage_nbr, cd.units_of_product, pk.to_store
from cage_dtl cd
left join item_master im
on im.sku_id = cd.sku_id and im.barcode = '105683004'
LEFT JOIN pkt_hdr pk
ON pk.pkt_ctrl_nbr = cd.pkt_ctrl_nbr
where cd.open_cage_batch = 31102014
and pk.to_store IS NULL

I learned how to SELECT FROM (SELECT's) here:
SQL SELECT Union SELECT FROM (Select...)
In this case, it would be something like...
SELECT (columns)
FROM
(select cd.cage_nbr, cd.units_of_product, pk.to_store
from cage_dtl cd
inner join item_master im on im.sku_id=cd.sku_id
INNER JOIN pkt_hdr pk ON pk.pkt_ctrl_nbr=cd.pkt_ctrl_nbr
where im.barcode = '105683004'
and cd.open_cage_batch = 31102014
) AS dispatched
JOIN
(select sd.to_store, sd.alloc_qty, sd.alloc_batch, im.size_desc
from store_distro sd
inner join item_master im on im.sku_id=sd.sku_id
where im.barcode = '105683004'
and sd.alloc_batch = 31102014
) AS allocated
ON (stuff)

Related

Use name of controllers to find table name in Select

I want to extract a ID , User_ID value from one of the Companies and Contract tables, depending on the ContorollerName value.
select P.TitleProject, P.StartDateProject, P.EndDateProject,P.ControllerID,P.RecordID,P.IsAllocated,P.ProjectStatus_ID,
CN.ControllerName,CN.PersianName,
PU.ProjectID,PU.UserID,PU.RoleID,
CASE
WHEN CN.ControllerName = 'Company' THEN
Companies.Id,Companies.[User_Id]
WHEN CN.ControllerName = 'Contract' THEN
Contracts.Id,Contracts.[User_Id]
END
from Projects P
left outer join Controllers CN ON P.ControllerID = CN.Id
left outer join ProjectUsers PU ON P.Id = PU.ProjectID
where P.IsAllocated = 1
For example, if ContorollerName is 'Company' , the select command is as follows :
select P.TitleProject, P.StartDateProject, P.EndDateProject,P.ControllerID,P.RecordID,P.IsAllocated,P.ProjectStatus_ID,
CN.ControllerName,CN.PersianName,
PU.ProjectID,PU.UserID,PU.RoleID,
Companies.Id,Companies.[User_Id]
You are on the right track -- using left join. But you need to add the tables to the from clause with the appropriate logic.
The logic for the join is quite unclear. The query looks something like this:
select . . .,
coalesce(c.id, co.id) as id,
coalesce(c.user_id, co.user_id) as user_id
from Projects P left join
Controllers CN
on P.ControllerID = CN.Id left join
ProjectUsers PU
on P.Id = PU.ProjectID left join
companies c
on c.? = ? and -- no idea what the right join conditions are
c.ControllerName = 'Company' left join
contracts co
on co.? = ? and -- no idea what the right join conditions are
co.ControllerName = 'Contract'
where P.IsAllocated = 1

Getting data from a join tables tu sub categories in access with SQL

I created this relationship with Access database but when I am creating a query to return the values I dont get the all the data.
How can I get all the data from tube and tmc tables by ProjectType or ProjectId ?
So I should get something like this query but the query generated by access is not working
SELECT Project.ProjectName,
ProjectSubTypesId.ProjectSubTypesId,
Tube.TubeName, Tube.Duration,
Tmc.TmcName
FROM Tmc
INNER JOIN
(Tube INNER JOIN
(Project INNER JOIN ProjectSubTypesId ON Project.ProjectId = ProjectSubTypesId.ProjectId)
ON Tube.TubeId = ProjectSubTypesId.TubeId) ON Tmc.TmcId = ProjectSubTypesId.TmcId;
Try this:
SELECT Project.ProjectName,
ProjectSubTypesId.ProjectSubTypesId
FROM (
(ProjectSubTypes
INNER JOIN Project USING (ProjectId)
)
INNER JOIN Tube USING(TubeId)
)
INNER JOIN Tmc USING(TmcId)
GROUP BY ProjectSubTypes.ProjectId, ProjectSubTypes.TubeId, ProjectSubTypes.TmcId
ORDER BY ProjectSubTypes.ProjectId;
Something like this work?
SELECT Project.ProjectName,
ProjectSubTypesId.ProjectSubTypesId,
Tube.TubeName, Tube.Duration,
Tmc.TmcName
FROM ((ProjectSubTypes
INNER JOIN Project ON Project.ProjectId = ProjectSubTypes.ProjectId)
INNER JOIN Tube ON Tube.TubeId = ProjectSubTypes.TubeId)
INNER JOIN Tmc ON Tmc.TmcId = ProjectSubTypes.TmcId
ORDER BY ProjectSubTypes.ProjectId;
This should give you a list of all sub-types along with their corresponding Tube, Tmc, and Project data.
If it is possible to have multiple ProjectSubTypes rows with the same TubeId and TmcId then consider adding this line before the ORDER BY line:
GROUP BY ProjectSubTypes.ProjectId, ProjectSubTypes.TubeId, ProjectSubTypes.TmcId

Reduce Runtime of T-SQL Query

-- WITH POD was causing the issue, removing this code reduced 2 year pull to 3 mins.
Will post new question to figure out best way to include POD data.
--Edit for clarity, I am a read only user to these tables.
I wrote the below query, but it takes a very long time to execute (20min).
It is currently limited to 1 month, but user wants at least 1 year preferably 2. I assume this would scale time to hours.
Can anyone take a look at let me know if there is a BKM I am not using to improve performance?
Or if there is a better method for a report of this size? At 2 years, it would return ~100K rows from 17 tables.
WITH
POD AS
(
SELECT SHIPMENTS.Delivery
,SHIPMENTS.Shipment_Number
,PROOF_OF_DELIVERY.Shipping_Carrier
,PROOF_OF_DELIVERY.Tracking_Number
,PROOF_OF_DELIVERY.Ship_Method
,PROOF_OF_DELIVERY.POD_Signature
,PROOF_OF_DELIVERY.POD_Date
,PROOF_OF_DELIVERY.POD_Time
FROM
SHIPMENTS
LEFT JOIN PROOF_OF_DELIVERY
ON SHIPMENTS.Shipment_Number = PROOF_OF_DELIVERY.Delivery_Or_Shipment
WHERE Load_Date IN
(
SELECT MAX(Load_Date)
FROM PROOF_OF_DELIVERY
GROUP BY Delivery_Or_Shipment
)
)
SELECT DISTINCT GI.GOODS_ISSUE_DOCUMENT_ID
,GI.SALES_ORDER_ID
,GI.SALES_ORDER_LINE_ID
,GI.SALES_ORDER_TYPE_CODE
,GI.DELIVERY_HEADER_ID
,GI.DELIVERY_ITEM_ID
,FD.FISCAL_MONTH_CODE
,GI.MATERIAL_NUMBER
,GI.SHIPPED_QTY
,SO.ORDERER_NAME
,SO.CREATED_BY
,SO.CONTACT_PERSON
,GI.SOLD_TO_CUSTOMER_ID
,GI.SHIP_TO_CUSTOMER_ID
,GI.ORIGINAL_COMMIT_DATE
,GI.SHIP_FROM_PLANT_ID
,GI.ACTUAL_PGI_DATE
,GI.CUSTOMER_PO_NUMBER
,GI.SHIPPED_PRICE
,(GI.SHIPPED_PRICE * GI.SHIPPED_QTY) AS EXT_SHIPPED_PRICE
,GI.SALES_ORGANIZATION_CODE
,GI.DELIVERY_NOTE_PRIORITY_CODE
,FD.FISCAL_WEEK_CODE
,DV.DIVISION_CODE
,DN.Delivery_Item_Creation_Date
,SOLD.CUSTOMER_SHORT_NAME AS SOLD_TO_CUSTOMER_SHORT_NAME
,SHIP.CUSTOMER_SHORT_NAME AS SHIP_TO_CUSTOMER_SHORT_NAME
,SHIP.Customer_Site_Name
,SHIP.REGION_NAME
,MATD.MATERIAL_DESCRIPTION
,MATD.STANDARD_COST
,(MATD.STANDARD_COST * GI.SHIPPED_QTY) AS EXT_STANDARD_COST
,MATD.GLOBAL_EVENT
,PLT.LEAD_TIME_FOR_ORIGINAL_COMMIT
,OPRM.BASE_PART_CODE
,MATD.PRODUCT_INSP_MEMO
,MATD.MATERIAL_PRICING_GROUP_CODE
,MATD.MATERIAL_STATUS AS MMPP
,PIM.PIM_PBG_GROUPING
,SOL.SHIPPING_CONDITION
,SVO.SERVICE_ORDER_NUM
,SO.CREATION_TIME AS SO_CREATION_TIME
,SOL.CREATED_TIME AS SO_LINE_CREATED_TIME
,SOL.SHIPPING_POINT
,SDT.SALES_DOCUMENT_TYPE_CODE AS SVO_DOCUMENT_TYPE_CODE
,EQU.EQUIPMENT_NUM
,EQU.SERIAL_NUMBER
,EQU.CUSTOMERTOOLID
,POD.Shipment_Number
,POD.Shipping_Carrier
,POD.Tracking_Number
,POD.Ship_Method
,POD.POD_Signature
,POD.POD_Date
,POD.POD_Time
,DATEDIFF(dd,SO.CREATION_TIME,GI.ACTUAL_PGI_DATE) AS Cycle_Time_to_PGI_Days
,DATEDIFF(hh,SO.CREATION_TIME,GI.ACTUAL_PGI_DATE) AS Cycle_Time_to_PGI_Hours
FROM GOODS_ISSUE AS GI
INNER JOIN dbo.Delivery_Notes AS DN
ON GI.DELIVERY_HEADER_ID = DN.DELIVERY_HEADER_CODE AND GI.DELIVERY_ITEM_ID = DN.DELIVERY_ITEM_CODE
INNER JOIN dbo.Customer_View AS SOLD
ON GI.SOLD_TO_CUSTOMER_ID = SOLD.CUSTOMER_CODE
INNER JOIN dbo.Customer_View AS SHIP
ON GI.SOLD_TO_CUSTOMER_ID = SHIP.CUSTOMER_CODE
INNER JOIN dbo.MATERIAL_DETAILS AS MATD
ON GI.MATERIAL_NUMBER = MATD.MATERIAL_NUMBER
INNER JOIN dbo.OPR_MATERIAL_DIM AS OPRM
ON OPRM.MATERIAL_NUMBER = GI.MATERIAL_NUMBER
LEFT JOIN dbo.SM_DATE_DIM AS FD
ON CAST(FD.CALENDAR_DAY AS DATE) = CAST(GI.ACTUAL_PGI_DATE AS DATE)
LEFT JOIN dbo.DIM_PUBLISHED_LEAD_TIME_COMMIT AS PLT
ON PLT.MATERIAL_NUMBER = OPRM.BASE_PART_CODE
LEFT JOIN dbo.PRODUCT_INSP_MEMO_DIM AS PIM
ON PIM.PRODUCT_INSP_MEMO = MATD.PRODUCT_INSP_MEMO
INNER JOIN dbo.SM_SALES_ORDER_LINE_FACT AS SOL
ON SOL.SALES_ORDER_CODE = GI.SALES_ORDER_ID AND SOL.SALES_ORDER_LINE_CODE = GI.SALES_ORDER_LINE_ID
INNER JOIN dbo.SM_SALES_ORDER_FACT AS SO
ON SO.SALES_ORDER_CODE = GI.SALES_ORDER_ID
INNER JOIN dbo.SM_DIVISION_DIM AS DV
ON SO.DIVISION_SID = DV.DIVISION_SID
LEFT JOIN dbo.SERVICE_ORDER_FACT AS SVO
ON SVO.SERVICE_ORDER_NUM = SO.SERVICE_ORDER_NUMBER
LEFT JOIN dbo.SM_SALES_DOCUMENT_TYPE_DIM AS SDT
ON SDT.SALES_DOCUMENT_TYPE_SID = SVO.SALES_DOCUMENT_TYPE_SID
LEFT JOIN dbo.SM_EQUIPMENT_DIM AS EQU
ON EQU.EQUIPMENT_SID = SVO.EQUIPMENT_SID
LEFT JOIN POD
ON POD.Delivery = GI.DELIVERY_HEADER_ID
WHERE GI.ACTUAL_PGI_DATE > GETDATE()-32
AND SOLD_TO_CUSTOMER_ID IN (0010000252,0010000898,0010001121,0010001409,0010001842,0010001852,0010001879,0010001977,0010001978,0010002021,0010002202,0010002227,0010002982,0010003118,0010003176,0010003294,0010005492,0010006904,0010007048,0010007080,0010010381,0010010572,0010010905,0010011999,0010012014,0010012048,0010012571,0010013124,0010013711,0010013713,0010013824,0010014180,0010014188,0010014333,0010015059,0010015313,0010015414,0010015541,0010015544,0010015550)
A CTE is just syntax
I suspect that CTE is evaluated many times
Materialze the CTE to #temp with indexe(s) so it is run once
This cast will hurt it
Make those columns true dates and index them
ON CAST(FD.CALENDAR_DAY AS DATE) = CAST(GI.ACTUAL_PGI_DATE AS DATE)
That where negates the left so you can just do a join
Also that MAX(Load_Date) could match on another shipment
SELECT SHIPMENTS.Delivery
,SHIPMENTS.Shipment_Number
,PROOF_OF_DELIVERY.Shipping_Carrier
,PROOF_OF_DELIVERY.Tracking_Number
,PROOF_OF_DELIVERY.Ship_Method
,PROOF_OF_DELIVERY.POD_Signature
,PROOF_OF_DELIVERY.POD_Date
,PROOF_OF_DELIVERY.POD_Time
FROM SHIPMENTS
JOIN PROOF_OF_DELIVERY
ON SHIPMENTS.Shipment_Number = PROOF_OF_DELIVERY.Delivery_Or_Shipment
WHERE PROOF_OF_DELIVERY.Load_Date IN
(
SELECT MAX(Load_Date)
FROM PROOF_OF_DELIVERY
GROUP BY Delivery_Or_Shipment
)
Pull this up into the join
INNER JOIN dbo.Customer_View AS SOLD
ON GI.SOLD_TO_CUSTOMER_ID = SOLD.CUSTOMER_CODE
AND GI.SOLD_TO_CUSTOMER_ID IN (0010000252,0010000898,0010001121,0010001409,0010001842,0010001852,0010001879,0010001977,0010001978,0010002021,0010002202,0010002227,0010002982,0010003118,0010003176,0010003294,0010005492,0010006904,0010007048,0010007080,0010010381,0010010572,0010010905,0010011999,0010012014,0010012048,0010012571,0010013124,0010013711,0010013713,0010013824,0010014180,0010014188,0010014333,0010015059,0010015313,0010015414,0010015541,0010015544,0010015550)

Getting SQL Error: ORA-00957: duplicate column name, while creating view

I am trying to make a view, but I am getting a duplicate column name error. If I run the select query separately, then the query returns a result like:
SELECT distinct app.APP_REF_NO, app.APP_STATUS, app.APP_DT, app.ATTEND_STAFF,
app.ATTEND_BRANCH, app.PRODUCT_TYPE, cust.CUST_ID,
cust.APP_JOINT_T, cust.ID1_TYPE, cust.ID1, cust.ID2_TYPE,
cust.ID2, cust.FIRST_NAME, cust.LAST_NAME, cust.FULL_NAME,
cust.FULL_NAME_CAP, cust.DOB, fac.FACILITY_NO, fac.PRODUCT_TYPE,
fac.PRODUCT_CODE, fac.MAIN_PROD_IND, fac.AMT_APPLIED
FROM
LOSA_APP app
LEFT JOIN
LOSA_CUST cust
ON
cust.APP_REF_NO = app.APP_REF_NO
LEFT JOIN
LOSA_FACILITIES fac
ON
fac.APP_REF_NO = app.APP_REF_NO
LEFT JOIN
OS_CURRENTSTEP STEP
ON
STEP.REF_ID = app.APP_REF_NO
WHERE (app.APP_STATUS ='P' OR app.APP_STATUS ='T' OR
((app.APP_STATUS='R' OR app.APP_STATUS='S') AND STEP.STEP_NAME='011'));
This query works fine. But when I try to run it as a view like:
CREATE VIEW basit_test1 AS
SELECT distinct app.APP_REF_NO, app.APP_STATUS, app.APP_DT, app.ATTEND_STAFF,
app.ATTEND_BRANCH, app.PRODUCT_TYPE, cust.CUST_ID,
cust.APP_JOINT_T, cust.ID1_TYPE, cust.ID1, cust.ID2_TYPE,
cust.ID2, cust.FIRST_NAME, cust.LAST_NAME, cust.FULL_NAME,
cust.FULL_NAME_CAP, cust.DOB, fac.FACILITY_NO, fac.PRODUCT_TYPE,
fac.PRODUCT_CODE, fac.MAIN_PROD_IND, fac.AMT_APPLIED
FROM
LOSA_APP app
LEFT JOIN
LOSA_CUST cust
ON
cust.APP_REF_NO = app.APP_REF_NO
LEFT JOIN
LOSA_FACILITIES fac
ON
fac.APP_REF_NO = app.APP_REF_NO
LEFT JOIN
OS_CURRENTSTEP STEP
ON
STEP.REF_ID = app.APP_REF_NO
WHERE (app.APP_STATUS ='P' OR app.APP_STATUS ='T' OR
((app.APP_STATUS='R' OR app.APP_STATUS='S') AND STEP.STEP_NAME='011'));
Then I get the duplicate column name error. Why am I getting this error?
you have two product_type columns:
fac.PRODUCT_TYPE
and
app.PRODUCT_TYPE
you should alias one of them eg
app.PRODUCT_TYPE app_prod_type

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