Error when trying to join a view in linq-to-sql - linq-to-sql

While trying to extract data from a view by joining it with two other tables, I'm getting the following error: "SQL Server does not handle comparison of NText, Text, Xml, or Image data types."
And here is the query:
var expeditions = from VE in context.ViewExpeditions
join SIAGR in context.SiteInAdviseGoodsRef on VE.DeliveryNotes equals SIAGR.Value
join SIA in context.SiteInAdvise on SIAGR.SiteInAdviseId equals SIA.Id
where SIA.Id == SiteInAdviseID
select VE;
Here is the View ViewExpeditions:
SELECT ve.*, S.[$Refex] as SiteRefex,c.[$Refex] as ServiceRefex , DeliveryNotes = LEFT(o.list, LEN(o.list)-1),st.Status,st.StatusRefex
from(
SELECT
B.[$Id] AS Booking,
B.[$Refex] AS BookingRefex,
B.SiguxCPUE AS CartaDePorte,
SUM(ISNULL(BG.Weight, 0)) AS Weight,
SUM(ISNULL(BG.Volume, 0)) AS Volume,
ISNULL( SUBSTRING(B.Comments, 1, 100),'') AS Comments,
'Type' =
CASE
WHEN PickupSite IS NULL THEN 'Pickup'
ELSE 'Delivery'
END,
'Name' =
CASE
WHEN PickupSite IS NULL THEN PickupName
ELSE DeliveryName
END,
'City' =
CASE
WHEN PickupSite IS NULL THEN PickupCity
ELSE DeliveryCity
END,
'PostalCode' =
CASE
WHEN PickupSite IS NULL THEN PickupPostalCode
ELSE DeliveryPostalCode
END,
'ContactName' =
CASE
WHEN PickupSite IS NULL THEN ISNULL(B.PickupContactName,'')
ELSE ISNULL(B.DeliveryContactName,'')
END,
'ContactPhone' =
CASE
WHEN PickupSite IS NULL THEN ISNULL(B.PickupContactPhone,'')
ELSE ISNULL( B.DeliveryContactPhone,'')
END,
B.PickupDate AS DataExp,
B.DeliveryDate,
coalesce( B.PickupSite,B.DeliverySite) as 'Site',
b.Service,isnull(B.SiguxState,0) as SiguxState
FROM dbo.BookingGoods AS BG
INNER JOIN dbo.Booking AS B ON BG.BookingId = B.[$Id]
WHERE (B.ExecutedBy = 2) AND B.SiguxCPUE is not null AND B.[$IsDeleted]=0
GROUP BY B.PickupCity,b.PickupContactName,b.PickupContactPhone,b.PickupName,b.PickupPostalCode, B.DeliveryName,B.DeliverySite, B.DeliveryCity, B.DeliveryPostalCode, B.DeliveryContactName, B.DeliveryContactPhone, B.PickupDate, B.[$Id], B.SiguxCPUE, B.[$Refex], B.Comments,b.PickupSite,B.Service,B.SiguxState,B.DeliveryDate
) ve
INNER join [ViewBookingActualStatus] st on st.Booking=ve.Booking
INNER join Service c on ve.Service=c.[$Id]
INNER JOIN dbo.Site AS S ON S.[$Id] = ve.Site
outer APPLY
(
SELECT distinct
CONVERT(VARCHAR(12), dbo.BookingGoodsRef.Value) + ', ' AS [text()]
FROM
dbo.BookingGoodsRef
WHERE
dbo.BookingGoodsRef.BookingId = ve.Booking and BookingGoodsRef.Type=13
FOR XML PATH('')
) o (list)
Where am I going wrong about this?
NOTE: If I try to run the query in linqpad, it doesn't give me any errors at all, and generates the following sql:
SELECT [t0].[Booking], [t0].[BookingRefex], [t0].[CartaDePorte], [t0].[Weight], [t0].[Volume], [t0].[Comments], [t0].[Type], [t0].[Name], [t0].[City], [t0].[PostalCode], [t0].[ContactName], [t0].[ContactPhone], [t0].[DataExp], [t0].[DeliveryDate], [t0].[Site], [t0].[Service], [t0].[SiguxState], [t0].[SiteRefex], [t0].[ServiceRefex], [t0].[DeliveryNotes], [t0].[Status], [t0].[StatusRefex]
FROM [ViewExpeditions] AS [t0]
INNER JOIN [SiteInAdviseGoodsRef] AS [t1] ON [t0].[DeliveryNotes] = [t1].[Value]
INNER JOIN [SiteInAdvise] AS [t2] ON [t1].[SiteInAdviseId] = [t2].[$Id]
WHERE [t2].[$Id] = #p0

If you copy the generated SQL from LinqPad into SSMS and try to run it, do you get the results you expect?
I'd guess that the one of the columns on which you're joining (probably DeliveryNotes) is ntext or text. SQL Server can't join on text columns - you have to either cast both columns to varchar or use a substring on both columns.

Related

mysql: duplicate column name on join with subquery

I've searched a lot but I still don't get it.
Here's my sample code
SELECT sp.testno, sp.companyid, st.*
FROM sponsor AS sp
LEFT JOIN
(
SELECT a.sponsorempno, (CASE WHEN t.companyid IS NULL OR t.companyid = '' THEN'aa' ELSE t.companyid END) agncy, a.controlno, a.tnpl, t.*
FROM applicant AS a
LEFT JOIN
test AS t
ON a.controlno = t.controlno
) AS st
ON sp.testno = st.testno
I still returns an error:
#1060 - Duplicate column name 'controlno'
Can somebody tell me what's wrong with the code?
In the subselect of your join, you are selecting a.controlno and by t.* t.controlno.
You should provide an alias for one of the selected columns. In your case a.controlno. This is necessary, because the table aliases of the inner select are lost, when accessing it from the outer one.
The statement below should work, if there aren't any other duplicate column names in test and the set of used columns from applicant.
SELECT sp.testno, sp.companyid, st.*
FROM sponsor AS sp
LEFT JOIN
(
SELECT a.sponsorempno, (CASE WHENt.companyid IS NULL OR t.companyid = '' THEN'aa' ELSE t.companyid END) agncy, a.controlno as a_controlno, a.tnpl, t.*
FROM applicant AS a
LEFT JOIN
test AS t
ON a.controlno = t.controlno
) AS st
ON sp.testno = st.testno

How would I constrain my CONCAT statement to just the id from the if statement in MySQL

I've been beating my head against the wall for a while now on this. I've tried following the thought behind Concat in If statement but I can't seem to figure out a way to make my specific need work. I'm now down to a syntax error in my CONCAT statement..'WHERE req.reqCreatedBy = '0' THEN 'Unknown' ELSE users.firstname,' ',users.lastn'. Could anybody give me some help on bringing the first and last name in on this query? I'm at a complete loss.
SELECT req.reqID as Id,
reqDesc.titleText as Title,
req.reqCity as City,
req.reqState as State,
req.areaID as Area,
area.areaname,
reqType.typeTitle as Type,
req.reqCreatedDate as Created,
req.reqEndDate as `End`,
CONCAT((CASE WHERE req.reqCreatedBy = '0' THEN 'Unknown' ELSE users.firstname,' ',users.lastname END))
AS Recruiter
FROM apps_job_request as req
INNER JOIN apps_job_request_description as reqDesc
ON req.reqTitle = reqDesc.titleID
INNER JOIN apps_job_request_type as reqType
ON reqDesc.typeID = reqType.typeID
INNER JOIN `assemble_users`.area AS area
ON area.areaid = req.areaID
INNER JOIN `assemble_users`.users AS users
ON users.username = req.reqCreatedBy
WHERE req.reqID is not null
AND req.reqActive = '1'
If check only one value req.reqCreatedBy, there may be simple IF statement, use CASE for multiple checked values.
SELECT req.reqID as Id,
reqDesc.titleText as Title,
req.reqCity as City,
req.reqState as State,
req.areaID as Area,
area.areaname,
reqType.typeTitle as Type,
req.reqCreatedDate as Created,
req.reqEndDate as `End`,
-- req.reqCreatedBy is '0' OR ''?
IF(req.reqCreatedBy = '0', 'Unknown', CONCAT(users.firstname, ' ', users.lastname)) AS Recruiter
FROM apps_job_request as req
INNER JOIN apps_job_request_description as reqDesc
ON req.reqTitle = reqDesc.titleID
INNER JOIN apps_job_request_type as reqType
ON reqDesc.typeID = reqType.typeID
INNER JOIN `assemble_users`.area AS area
ON area.areaid = req.areaID
INNER JOIN `assemble_users`.users AS users
ON users.username = req.reqCreatedBy
WHERE req.reqID is not null
AND req.reqActive = '1'

Include another select column based on data - MySQL

How do I include SUM((pm.Quantity * bl.TotalQty)) AS NextBOMItemCount WHERE projectbomlist.ParentPartNum = bl.PartNum?
The data should not be changed, the same data should be retrieved, the however additional column has to be included.
VIEW: `NEWprojectBOMItemCount
select
`pm`.`ProjectCode` AS `ProjectCode`,
`bl`.`PartNum` AS `PartNum`,
sum((`pm`.`Quantity` * `bl`.`TotalQty`)) AS `BOMItemCount`,
`bl`.`mp` AS `mp`,
`p`.`complete` AS `complete`,
`bl`.`RMInd` AS `RMInd`,
`bl`.`M_PartNum` AS `M_PartNum`
from
(
(`projectmachine` `pm` join `projectbomlist` `bl`)
join `projects` `p`
)
where
(
(`pm`.`MachineListID` = `bl`.`MachineListID`)
and (`pm`.`ProjectCode` = `bl`.`ProjectCode`)
and (`pm`.`ProjectCode` = `p`.`ProjectCode`)
and (`p`.`AfterProjectHeirarchyInd` = 'Y')
)
and and pm.ProjectCode = 'AB212323'
group by
`pm`.`ProjectCode` ,
`bl`.`PartNum`
order by
`pm`.`ProjectCode` ,
`bl`.`PartNum`
Or, another option can be, please consider above view used in below query, please suggest changes to the below query as shown above (repeating here)
`sum((pm.Quantity * bl.TotalQty)) AS NextBOMItemCount where projectbomlist.ParentPartNum = bl.PartNum` - in place of `(select-NextBOMItemCount)`?
Please see PBLH.ParentPartNum is the column that I should compare with BL.ProjectCode to get NextBOMItemCount value.
QUERY calling view: NEWprojectBOMItemCount
Select
BL.PartNum PartNumber,
PBLH.ParentPartNum NextBOM,
(select-NextBOMItemCount),
BOMItemCount TotalQty,
PL.Description,
BL.MP as PartType,
PL.Vendor,
PL.QBType
from
NEWprojectBOMItemcount BL,
bomwiz.partslist PL,
bomwiz.projectbomlistheirarchy PBLH
Where
BL.PartNum = PL.PartNum
And BL.PartNum = PBLH.PartNum
And BL.ProjectCode = PBLH.ProjectCode
And BL.projectCode = 'AB212323'
Order By PartNumber
I think that you are looking for conditional aggregation. Your requirement could be expressed as follows:
SUM(
CASE WHEN blh.ParentPartNum = bl.PartNum
THEN pm.Quantity * bl.TotalQty
ELSE 0
END
) AS NextBOMItemCount
Let me pinpoint other issues with your query:
you have unwanted parentheses all around, and I am suspicious about the syntax of the JOINs ; you need to move conditions to the ON clause of the relevant JOIN.
every non-aggregated column must appear in the GROUP BY clause - you have missing columns there
backquotes are usually not needed
Here is an updated version of the query:
SELECT
pm.ProjectCode AS ProjectCode,
bl.PartNum AS PartNum,
SUM(pm.Quantity * bl.TotalQty) AS BOMItemCount,
SUM(
CASE WHEN blh.ParentPartNum = bl.PartNum
THEN pm.Quantity * bl.TotalQty
ELSE 0
END
) AS NextBOMItemCount,
bl.mp AS mp,
p.complete AS complete,
bl.RMInd AS RMInd,
bl.M_PartNum AS M_PartNum
FROM
projectmachine AS pm
INNER JOIN projectbomlist AS bl
ON pm.MachineListID = bl.MachineListID
AND pm.ProjectCode = bl.ProjectCode
INNER JOIN join projects AS p
ON pm.ProjectCode = p.ProjectCode
AND p.AfterProjectHeirarchyInd = 'Y'
INNER JOIN projectbomlistheirarchy blh
ON bl.ProjectCode = blh.ProjectCode
WHERE
pm.ProjectCode = 'AB212323'
GROUP BY
pm.ProjectCode,
bl.PartNum,
bl.mp,
p.complete,
bl.RMInd,
bl.M_PartNum
ORDER BY
pm.ProjectCode,
bl.PartNum

How can I create a WHERE clause where there are some mandatory fields and some other optional fields in a SQL query

I am not so into database and I have the following doubt. I am using MySql
I have this query that return multiple records (it works fine) and I have to add the WHERE clause in such a way that some fields are mandatory and some other fields are optional.
So I have this query:
SELECT
EnutrifoodMessage.content
, MessageType.message_type_name
, Country.country_name
, IFNULL(Province.province_name, 'All Provinces') as province_name
, IFNULL(District.district_name, 'Any District') as district_name
, Crop.crop_name
, EnutriMessageDetails.creation_date
, EnutriMessageDetails.message_important_days
, temp_scale.scale_name as temperature
, humidity_scale.scale_name as humidity
, ProcessPhase.phase_name
, ProcessPhaseAction.process_phase_action_name
, Urgency.urgency_name as action
, IFNULL(MeteoWarningDescription.meteo_warning_description_name, '') as emergency
, IFNULL(EnutriMessageDetails.internal_link, '') as internal_link
, IFNULL(EnutriMessageDetails.reference_link, '') as reference_link
, IFNULL(EnutriMessageDetails.external_link, '') as external_link
, IFNULL(cleared_by_institution.institution_name, '') as message_cleared_by
, UserType.user_type_name as end_user
, provider.institution_name as provider
, ValueAddition.value_addition_name
FROM EnutriMessageDetails
LEFT JOIN EnutrifoodMessage
ON EnutrifoodMessage.id = EnutriMessageDetails.enutri_food_message_id
LEFT JOIN MessageType
ON MessageType.id = EnutriMessageDetails.message_type_id
LEFT JOIN Localization
ON Localization.id = EnutriMessageDetails.localization_id
LEFT JOIN Country
ON Country.id = Localization.country_id
LEFT JOIN Province
ON Province.id = Localization.province_id
LEFT JOIN District
ON District.id = Localization.district_id
LEFT JOIN Crop
ON Crop.id = EnutriMessageDetails.crop_id
LEFT JOIN Scale temp_scale
ON temp_scale.id = EnutriMessageDetails.temp_scale_id
LEFT JOIN Scale humidity_scale
ON humidity_scale.id = EnutriMessageDetails.humidity_scale_id
LEFT JOIN ProcessPhase
ON ProcessPhase.id = EnutriMessageDetails.process_phase_id
LEFT JOIN ProcessPhaseAction
ON ProcessPhaseAction.id = EnutriMessageDetails.process_phase_action_id
LEFT JOIN Urgency
ON Urgency.id = EnutriMessageDetails.urgency_id
LEFT JOIN MeteoWarningDescription
ON MeteoWarningDescription.id = EnutriMessageDetails.meteo_warning_description_id
LEFT JOIN Institution cleared_by_institution
ON cleared_by_institution.id = EnutriMessageDetails.cleared_by_id
LEFT JOIN UserType
ON UserType.id = EnutriMessageDetails.user_type_id
LEFT JOIN Institution provider
ON provider.id = EnutriMessageDetails.provided_by_id
LEFT JOIN ValueAddition
ON ValueAddition.id = EnutriMessageDetails.value_addition_id
WHERE Localization.id = 2
AND Crop.id = 2
ORDER BY EnutrifoodMessage.id
I need to add the WHERE clause in such a way that:
1) This field is mandatory:
Localization.id = 2
UserType.id = 1
2) These other fields are optional:
EnutriMessageDetails.creation_date >= a specified date
Urgency.id = 3
I want that the first type of field have to be inserted, the other type have to be optional and can be not fill.
How can I correctly handle this situation?
Try case expression:
Where Localization.id = 2 and UserType.id = 1 and
1 = case when EnutriMessageDetails.creation_date >= **[a specified date]**
then case when and Urgency.id = 3
then 1
else 0
end
else 1
end
Edit: Correction.
Please try the following to test if it will work this is to check if its null or not. So then you can react on it.
WHERE Urgency.id LIKE CASE WHEN Urgency.id IS NULL
THEN Urgency.id
ELSE CONCAT('%', Urgency.id, '%')
END
I dont have a testing environment for mySql so please check if it will work just trying to help.
It seems you want:
WHERE (urgency.id = #urgencyid OR #urgencyid IS NULL)
or
ON (urgency.id = #urgencyid OR #urgencyid IS NULL)
So when an ID is given, only data matching the ID will be selected, and if no ID is given, all data will.
The WHERE clause will not select any record if the ID does not exist in the table. So the urgency table should be inner-joined. If it is outer-joined, the WHERE clause turns it into an inner join, as records with ID null will be dismissed. Avoid such pseudo outer joins.
For an inner join it doesn not matter whether to use WHERE or ON. For an outer join, however, the WHERE clause would turn it into an inner join as mentioned, whereas the ON clause would still outer-join (with a given ID, either the ID is found or an empty dummy record joined).

MYSQL SELECT is slow when crossing multiple tables

I have a mysql query which is to return the only 1 record that need to cross multiple table. However, the mysql query is slow when executing.
Query:
SELECT *,
(SELECT TreeName FROM sys_tree WHERE TreeId = Mktg_Unit_Booking.ProjectLevelId) AS PhaseName,
(CASE WHEN ProductType = 'U' THEN (SELECT UnitNo FROM prop_unit pu WHERE pu.UnitId = mktg_unit_booking.UnitId)
ELSE (SELECT BayNo FROM prop_car_park pcp WHERE pcp.CarParkId = UnitId) END) AS UnitNo,
(SELECT CustomerName FROM mktg_customer mc WHERE mc.CustomerId = mktg_unit_booking.CustomerId) AS CustomerName
FROM Mktg_Unit_Booking
WHERE IsDeleted <> '1' AND IsApproved = '1'
AND UnitId = 1110 AND ProductType = 'U'
ORDER BY UnitNo
I have run EXPLAIN in the query and I got this:
Any other suggestion on how to improve the speed of the query?
Thank you!
you are doing the cross product, instead of that you should use join.
Don't use sub-queries in select statement instead use proper join on Mktg_Unit_Booking in after from statement.
you query should something look like :
select
sys_tree.TreeName AS PhaseName,
case
WHEN Mktg_Unit_Booking.ProductType = 'U' then prop_unit.UnitNo
else prop_car_park.BayNo
end as UnitNo,
mktg_customer.CustomerName AS CustomerName
FROM Mktg_Unit_Booking
left join sys_tree on sys_tree.TreeId = Mktg_Unit_Booking.ProjectLevelId
left join prop_unit on prop_unit.UnitId = Mktg_Unit_Booking.UnitId
left join prop_car_park on prop_car_park.CarParkId = Mktg_Unit_Booking.UnitId
left join mktg_customer on mktg_customer.CustomerId = Mktg_Unit_Booking.CustomerId
WHERE IsDeleted <> '1' AND IsApproved = '1'
AND UnitId = 1110 AND ProductType = 'U'
ORDER BY UnitNo;
I have assumed that each table consists of only 1 matching tuple. If there are more then your logic needs to be modified.