Microsoft SQL Server: Error with Group By - sql-server

I'm new to Microsoft SQL Server 2014. I run this SQL code:
SELECT TOP(10) 'DBSG' as seek_entity, *
FROM DBSG..PM00200
and get this result:
Next, I want to find out total line items for that entity with code below.
WITH vw_pm00200_all AS
(
SELECT TOP(10)
'DBSG' as seek_entity, *
FROM
DBSG..PM00200
)
SELECT
seek_entity,
COUNT(*) AS total
FROM
vw_pm00200_all
GROUP BY
1
Sadly, I get this error. I have no idea why it failed.
Msg 164, Level 15, State 1, Line 9
Each GROUP BY expression must contain at least one column that is not an outer reference.
Lastly, please advise is Microsoft SQL Server based on Transact-SQL?

It looks like you are running into this problem here: Each GROUP BY expression must contain at least one column that is not an outer reference
As the answer points out, grouping by a constant literal is pointless as it is the same for all results. Count(*) will return the same result as Count(*) with a GROUP BY.
If this is just test code and you plan on using a CASE statement (with different values) in place of the string literal, you may have better luck.
Yes, T-SQL is Microsoft SQL Server's flavor of SQL.

Related

SQL Server fetch next x number of rows with where clause

Microsoft SQL Server 2008 R2
I am running a large SQL select query that may take hours to complete. So I try to break the query results into smaller sets.
e.g return results 1-10,000 first, then 10,001 - 20000, and so on
I used below code, but it gave me error
SELECT *
FROM PP_ConsolidatedSalesView
WHERE financial_period = '2018-11'
ORDER BY id
OFFSET 10000 ROWS
FETCH NEXT 10000 ROWS ONLY
I use a loop to dynamically change the offset and fetch next values.
The error message is:
Incorrect syntax near 'OFFSET'
Does anyone have an idea why? And is there an alternative solution?
Can you please confirm the database compatibility level. Offset is present in SQL Server 2012. If database is 2008 compatbility mode, then keyword isnt available.
You can check it like below:
USE AdventureWorks2012;
GO
SELECT compatibility_level
FROM sys.databases WHERE name = 'AdventureWorks2012';
GO
More info here: Incorrect syntax near OFFSET command

Need Help Converting Oracle Query to SQL Server

Several weeks ago I made a post to get help with converting a comma delimited list of values into a format that it could be used as part of an IN clause in Oracle. Here is a link to the post.
Oracle invalid number in clause
The answer was to split up the list into an individual row for each value. Here's the answer that I ended up using.
SELECT trim(regexp_substr(str, '[^,]+', 1, LEVEL)) str
FROM ( SELECT '1,2,3,4' str FROM dual )
CONNECT BY instr(str, ',', 1, LEVEL - 1) > 0
Is there a way that I can do something similar in SQL Server without having to create a custom function? I noticed that there's a STRING_SPLIT function, but I don't seem to have access to that on this SQL Server.
Any advice you might have would be greatly appreciated. I've been trying to take a stab at this for the majority of the day.
String_split function is available in MS SQL Server starting from version 2016. If you use older version you can write a few lines of code which do the same.
declare #str varchar(100)='1,2,3,4' --initial string
;with cte as (--build xml from the string
select cast('<s>'+replace(#str,',','</s><s>')+'</s>' as xml) x
)
--receive rows
select t.v.value('.[1]','int') value
from cte cross apply cte.x.nodes('s') t(v)

adding WHERE clause to SQL Server Query panel

I'm in the Server Explorer and on the table name, I right-click on "Select Top 1000 Rows". The query panel show the SQL generated as
SELECT TOP 1000 [...] ,[....] , [....]
FROM [filename].[dbo].[TableName]
Now I want to add a simple WHERE clause.
I tried adding it like this:
WHERE [ColumnName] == 11
It's not working. I know this is a very basic question but I don't have much experience with working on SQL Server directly.
How do I fix the WHERE clause?
You don't need the double == sign SQL terminology is to use only a single =
From your example:
SELECT TOP 1000 [...] ,[....] , [....]
FROM [filename].[dbo].[TableName]
WHERE [ColumnName] = 11
C# uses double equal ("==") for conditional checks, in sql it is single "=" for predicates.

How to fix "domain error" in SQL Server 2005 when using LOG() function to get product of set

I have a inline select statement to calculate the product of the set of values.
Since SQL Server 2005 doesn't have a built in Product aggregate function, I am using LOG/EXP to get it.
My select statement is:
(select exp(sum(log(value))) from table where value > 0)
Unfortunately I keep getting the following error:
Msg 3623, Level 16, State 1, Line 1
A domain error occurred.
I've ensured that none of the values are zero or negative so I'm not really sure why this error is occurring. Does anyone have any ideas?
One of the features of the query planner introduced in SQL 2005 is that, in some circumstances where the table statistics indicate it will be more efficient, the WHERE clause of a statement will be processed after the SELECT clause.
(I can't find the Books On-Line reference for this right now).
I suspect this is what is happening here. You either need to exclude the rows where value = 0 before carrying out the calculation - the most reliable way being to store the rows you need in a temporary (#) table - or to modify your query to handle zero internally:
SELECT EXP(SUM(LOG(ISNULL(NULLIF(VALUE,0),1)))) AS result
FROM [table]
The NULLIF\ISNULL pair I have added to your query substitutes 1 for 0 - I think this will work, but you will need to test it on your data.

Incosistency between MS Sql 2k and 2k5 with columns as function arguments

I'm having trouble getting the following to work in SQL Server 2k, but it works in 2k5:
--works in 2k5, not in 2k
create view foo as
SELECT usertable.legacyCSVVarcharCol as testvar
FROM usertable
WHERE rsrcID in
( select val
from
dbo.fnSplitStringToInt(usertable.legacyCSVVarcharCol, default)
)
--error message:
Msg 170, Level 15, State 1, Procedure foo, Line 4
Line 25: Incorrect syntax near '.'.
So, legacyCSVVarcharCol is a column containing comma-separated lists of INTs. I realize that this is a huge WTF, but this is legacy code, and there's nothing that can be done about the schema right now. Passing "testvar" as the argument to the function doesn't work in 2k either. In fact, it results in a slightly different (and even weirder error):
Msg 155, Level 15, State 1, Line 8
'testvar' is not a recognized OPTIMIZER LOCK HINTS option.
Passing a hard-coded string as the argument to fnSplitStringToInt works in both 2k and 2k5.
Does anyone know why this doesn't work in 2k? Is this perhaps a known bug in the query planner? Any suggestions for how to make it work? Again, I realize that the real answer is "don't store CSV lists in your DB!", but alas, that's beyond my control.
Some sample data, if it helps:
INSERT INTO usertable (legacyCSVVarcharCol) values ('1,2,3');
INSERT INTO usertable (legacyCSVVarcharCol) values ('11,13,42');
Note that the data in the table does not seem to matter since this is a syntax error, and it occurs even if usertable is completely empty.
EDIT: Realizing that perhaps the initial example was unclear, here are two examples, one of which works and one of which does not, which should highlight the problem that's occurring:
--fails in sql2000, works in 2005
SELECT t1.*
FROM usertable t1
WHERE 1 in
(Select val
from
fnSplitStringToInt(t1.legacyCSVVarcharCol, ',')
)
--works everywhere:
SELECT t1.*
FROM usertable t1
WHERE 1 in
( Select val
from
fnSplitStringToInt('1,4,543,56578', ',')
)
Note that the only difference is the first argument to fnSplitStringToInt is a column in the case that fails in 2k and a literal string in the case that succeeds in both.
Passing column-values to a table-valued user-defined function is not supported in SQL Server 2000, you can only use constants, so the following (simpler version) would also fail:
SELECT *, (SELECT TOP 1 val FROM dbo.fnSplitStringToInt(usertable.legacyCSVVarcharCol, ','))
FROM usertable
It will work on SQL Server 2005, though, as you have found out.
I don't think functions can have default values in functions in SS2K.
What happens when you run this SQL in SS2K?
select val
from dbo.fnSplitStringToInt('1,2,3', default)

Resources