SQL Server passing table columns to a function's parameter - sql

I have an SQL function which returns the minimum and maximum selling price of an item. I'd like to make a query which gets other StockItem columns together with it's selling price
like so:
SELECT i.StockItemID ii,
i.Name,
i.Code,
pli.SellingPrice AS MinSellingPrice,
pli.StandardSellingPrice AS MaxSellingPrice,
i.WebDetailedDescription,
i.WebAdditionalInfo,
i.FeaturedItemDescription
FROM SC_StockItem AS i,
func_GetPrice(17, i.StockItemID, 5) pli
However this gives an error:
Msg 4104, Level 16, State 1, Line 12 The multi-part identifier
"i.StockItemID" could not be bound.
any idea how I can do this ?
Thanks in advance

If that is a table valued function, then you can use OUTER APPLY:
select i.StockItemID ii,
i.Name,
i.Code,
pli.SellingPrice as MinSellingPrice,
pli.StandardSellingPrice as MaxSellingPrice,
i.WebDetailedDescription,
i.WebAdditionalInfo,
i.FeaturedItemDescription
from SC_StockItem as i
OUTER APPLY func_GetPrice(17, i.StockItemID, 5) pli
From MSDN:
The APPLY operator allows you to invoke a table-valued function for each row returned by an outer table expression of a query.

Related

issue with using a Subquery with left join

I am having an issue while being left joining 2 tables using subquery, getting an error :
Msg 156, Level 15, State 1, Line 25
Incorrect syntax near the keyword 'FROM'.
Msg 102, Level 15, State 1, Line 36
Incorrect syntax near 'PM'.
Here is the query I was trying to achieve:
SELECT
 [SEASON],
SUM(B.QUANTITY) AS QUANTITY,
FROM
(SELECT
 QUANTITY, WAREHOUSE,
CASE SUBSTRING(sku, 3, 1)
WHEN '1' THEN 'SS'
ELSE 'FW'
END + SUBSTRING (sku, 1, 2) [SEASON]
FROM
Table
) B
As I stated in the comments, you have 2 FROM clauses. Presumably the latter should be a CROSS JOIN or CROSS/OUTER APPLY (we don't know which). You also alias your second derived table as PM and then alias the table PRODTABLE as PM; that isn't allowed either as you can't have 2 objects with the same alias in the same scope. As I can't guess what alias you mean in other locations, I put {Alias} in places you need to add the relevant alias.
I also remove the NOLOCK table hints; you didn't reply as to why you "need" them and with respect I doubt you understand what it does considering the comments and question; more likely you have picked up someone elses terrible habit (get rid of said bad habit now).
I also, finally, get rid of the other bad habit of single quote aliases (see my comment on that too) and schema qualify (assuming dbo):
SELECT {Alias}.[SEASON],
SUM(BL.QUANTITY) AS QUANTITY,
{Alias}.PRODUCT AS PRD_CLASS,
{Alias}.BRAND AS BRAND,
{Alias}.COST_PRICE AS COST,
{Alias}.DATECREATE
FROM (SELECT QUANTITY,
WAREHOUSE,
CASE SUBSTRING(EXTENDED, 3, 1)WHEN '1' THEN 'SS' ELSE 'FW' END + SUBSTRING(EXTENDED, 1, 2) AS [SEASON]
FROM dbo.BINLABE) BL
CROSS JOIN (SELECT PRODUCT AS PRDODUCT,
BRAND AS BRAND,
COST_PRICE AS COST,
DATECREATE AS DATE_CREATE
FROM dbo.PRODTABLE) PT
LEFT JOIN dbo.PRODTABLE PM ON BL.SKU = PM.SKU --Think we can safely assume this is PM
WHERE {Alias}.WAREHOUSE = '0001'
GROUP BY {Alias}.[SEASON]
ORDER BY {Alias}.[SEASON];

Filter on column values not in select

I am trying to do joins on two tables and filter on values that are not in my select statement.
The following query does not work.
select b.[[Product]].[Major Category]]] ,sum(a.BIC_ZCDP) from TEMP_FORECAST_ALL a
join OUT_Dimension_DP_Product b
on right(a.MATERIAL,10) = b.[[Product]].[10D]]]
join OUT_Dimension_DP_Market c
on a.BIC_ZRMARKET = c.[[Market]].[Market]]]
group by b.[[Product]].[Major Category]]]
having a.CALMONTH in ('201810','201811','201812') and c.[[Market]].[Region]]] = 'UK'
I get the following errors
Msg 8121, Level 16, State 1, Line 7
Column 'TEMP_FORECAST_ALL.CALMONTH' is invalid in the HAVING clause because it is not contained in either an aggregate function or the GROUP BY clause.
Msg 8121, Level 16, State 1, Line 7
Column 'TEMP_FORECAST_ALL.CALMONTH' is invalid in the HAVING clause because it is not contained in either an aggregate function or the GROUP BY clause.
Msg 8121, Level 16, State 1, Line 7
Column 'TEMP_FORECAST_ALL.CALMONTH' is invalid in the HAVING clause because it is not contained in either an aggregate function or the GROUP BY clause.
Msg 8121, Level 16, State 1, Line 7
Column 'OUT_Dimension_DP_Market.[Market].[Region]' is invalid in the HAVING clause because it is not contained in either an aggregate function or the GROUP BY clause.
I don't want to add Region and CALMONTH in my group by clause.
Use a WHERE clause . . . :
select p.[[Product]].[Major Category]]], sum(a.BIC_ZCDP)
from TEMP_FORECAST_ALL a join
OUT_Dimension_DP_Product p
on right(a.MATERIAL,10) = b.[[Product]].[10D]]] join
OUT_Dimension_DP_Market m
on a.BIC_ZRMARKET = m.[[Market]].[Market]]]
where a.CALMONTH in ('201810', '201811', '201812') and
m.[[Market]].[Region]]] = 'UK'
group by p.[[Product]].[Major Category]]];
having is only for aggregates. Since this is just simple comparisons, you want them in a where clause. You'd use having if you were, for example, comparing to a sum or other aggregate.
Having clause is used when we are using aggregate function, but here you are simply doing comparison so you have to go with where clause.
A HAVING clause is used when you are filtering on aggregated data, i.e., if you wanted to filter on the results of the SUM statement, something like the following:
HAVING SUM(a.BIC_ZCDP) > 0
However, for the purposes of your query, you simply need to switch the HAVING to WHERE, as so...
SELECT
b.[[Product]].[Major Category]]],
SUM(a.BIC_ZCDP)
FROM
TEMP_FORECAST_ALL a
INNER JOIN OUT_Dimension_DP_Product b ON right(a.MATERIAL,10) = b.[[Product]].[10D]]]
INNER JOIN OUT_Dimension_DP_Market c ON a.BIC_ZRMARKET = c.[[Market]].[Market]]]
WHERE
(a.CALMONTH IN ('201810','201811','201812')) AND (c.[[Market]].[Region]]] = 'UK')
GROUP BY
b.[[Product]].[Major Category]]]
Again, a HAVING clause allows you to filter on fields that have been AGGREGATED (SUM, MAX, MIN, etc.), while a WHERE clause allows you to filter on normal fields.

SQL WHERE Statement With Multiple Account Numbers

I'm working with a SQL query and I need to display a set of information, but I have 5 records to display. The following query isn't working:
SELECT m.customer_number, m.last_name, m.billing_address_line_1, m.billing_address_line_2, m.billing_city, m.billing_state, m.phone_number1, c.equipment_serial_no, c.make, c.model_number, c.color_code
FROM customer_master as m
INNER JOIN equip_master as c ON m.customer_number = c.customer_number
WHERE m.customer_number = '19975107' AND '1039283' AND '39203821' AND '23824917' AND '1833729'
I get the following error:
Msg 4145, Level 15, State 1, Line 9 An expression of non-boolean type
specified in a context where a condition is expected, near '19978107'
That's not a valid syntax. If you want to get the list of customer_number then use IN clause.
....
WHERE m.customer_number in('19975107', '1039283', '39203821'
,'23824917' , '1833729')
You Have syntax error in your query.
It must be written like this
SELECT m.customer_number, m.last_name, m.billing_address_line_1,m.billing_address_line_2, m.billing_city, m.billing_state, m.phone_number1, c.equipment_serial_no, c.make, c.model_number, c.color_code
FROM customer_master as m
INNER JOIN equip_master as c
ON m.customer_number = c.customer_number
WHERE m.customer_number = '19975107' OR m.customer_number='1039283' OR m.customer_number='39203821' OR m.customer_number='23824917' OR m.customer_number ='1833729';
Note: Since customer_number is a primary key hence no two customer can have same value of it. Hence using AND is logically incorrect it will return empty set.

Multiple table query with count error

Whenever I add a count to the following select statement, it causes it to give me an error, and I'm not sure why:
select "WorkOrder"."WorkOrderID", "Vehicles"."Model", "Vehicles"."Color",
"Vehicles"."LicensePlate", COUNT("WorkOrderPart"."WorkPartID") AS "Parts"
FROM "WorkOrder", "Vehicles", "WorkOrderPart"
WHERE "WorkOrder"."VIN" = "Vehicles"."VIN" AND
"WorkOrder"."WorkOrderID" = "WorkOrderPart"."WorkOrderID";
Whenever I run this, I get the following error:
select "WorkOrder"."WorkOrderID", "Vehicles"."Model", "Vehicles"."Color",
*
ERROR at line 1:
ORA-00937: not a single-group group function
What can I do about this? I am running the SQL command line with an Oracle database.
When you have a count (or other aggregate function), you need to group by the non aggregated items
select
"WorkOrder"."WorkOrderID",
"Vehicles"."Model",
"Vehicles"."Color",
"Vehicles"."LicensePlate",
COUNT("WorkOrderPart"."WorkPartID") AS "Parts"
FROM "WorkOrder", "Vehicles", "WorkOrderPart"
WHERE "WorkOrder"."VIN" = "Vehicles"."VIN"
AND "WorkOrder"."WorkOrderID" = "WorkOrderPart"."WorkOrderID"
group by "WorkOrder"."WorkOrderID", "Vehicles"."Model", "Vehicles"."Color",
"Vehicles"."LicensePlate"
As an aside, it is considered good practice to use explicit joins (unless you're using a prehistoric version of oracle) instead of the where clause
FROM "WorkOrder"
inner join "Vehicles" on "WorkOrder"."VIN" = "Vehicles"."VIN"
left join "WorkOrderPart" on "WorkOrder"."WorkOrderID" = "WorkOrderPart"."WorkOrderID"

SQL Syntax Error Group By

I've got a sql syntax and it gives me the error:
Msg 8120, Level 16, State 1, Line 1 Column 'VEHICLEMASTR.cconduction'
is invalid in the select list because it is not contained in either an
aggregate function or the GROUP BY clause.
Here is the SQL syntax:
SELECT A.cplateno,A.cconduction,A.cname,A.cbatterymodel
,A.dbattery,A.DlastChange,A.nlastoilkm,A.naveragekmday
,A.dkmreading,A.dfranacq,A.dfranexp,A.nlimit,A.dreading
,CONVERT(varchar(2),month(MAX(B.dinsexp)))+'/'+CONVERT(varchar(2),day(MAX(B.dinsexp)))+'/'+CONVERT(varchar(4),year(MAX(B.dinsexp))) as dinsexp
,C.corno,CONVERT(varchar(2),month(MAX(C.dregexp)))+'/'+CONVERT(varchar(2),day(MAX(C.dregexp)))+'/'+ CONVERT(varchar(4),year(MAX(C.dregexp))) as dregexp
FROM VEHICLEMASTR A
LEFT JOIN VEHICLEINSURANCE B
ON A.cplateno = B.cplateno
LEFT JOIN VREGISTRATION C
ON A.cplateno = C.cplateno
GROUP BY A.cplateno
Can anybody tell what went wrong?
The "group by" clause must name every column selected, except those columns that are aggregate functions.
FYI an "aggregate" function is one that returns a single value for many rows, like sum(), count(), etc
a.cconduction needs to be in the group by clause.
When using a Group By clause, a column must either have an aggregate function (i.e. COUNT) or be defined in the group by.
A sample group by statement with multiple grouping:
SELECT column1_name, column2_name, aggregate_function(column_name3)
FROM table_name
WHERE column_name1 operator value
GROUP BY column_name1, column_name2;
You must include all fields that you mentioned in your select except the column that has aggregate function so in your case it would be:
GROUP BY
a.cplateno, a.cconduction,a.cname,a.cbatterymodel,a.dbattery,
a.DlastChange,a.nlastoilkm,a.naveragekmday,
a.dkmreading,a.dfranacq,a.dfranexp,a.nlimit,a.dreading
instead of
GROUP BY a.cplateno
Edit:
If you want only the a.cplateno then you don't include the rest of the fields except aggregate function and a.cplateno like:
SELECT A.cplateno
,CONVERT(varchar(2),month(MAX(B.dinsexp)))+'/'+CONVERT(varchar(2),day(MAX(B.dinsexp)))+'/'+CONVERT(varchar(4),year(MAX(B.dinsexp))) as dinsexp
,CONVERT(varchar(2),month(MAX(C.dregexp)))+'/'+CONVERT(varchar(2),day(MAX(C.dregexp)))+'/'+ CONVERT(varchar(4),year(MAX(C.dregexp))) as dregexp
FROM VEHICLEMASTR A
LEFT JOIN VEHICLEINSURANCE B
ON A.cplateno = B.cplateno
LEFT JOIN VREGISTRATION C
ON A.cplateno = C.cplateno
GROUP BY A.cplateno