I'm busy teaching myself SQL Server, using SQL Server Management Studio. Here's the code producing the error:
SELECT SalesPersonID, COUNT(SalesOrderID), YEAR(OrderDate) AS SalesYear
FROM Sales.SalesOrderHeader
GROUP BY SalesYear;
Why does it throw this error?
Invalid column name 'SalesYear'.
Invalid column name 'SalesYear'.
This column will not be there in table SalesOrderHeader
SELECT SalesPersonID, COUNT(SalesOrderID), YEAR(OrderDate) AS SalesYear
FROM Sales.SalesOrderHeader GROUP BY YEAR(OrderDate)
This has to do with logical query processing model..Sales year is called an alias here and as per logical query processing model,below are the operators that are executed in sequence..
1 FROM
2 WHERE
3 GROUP BY
4 HAVING
5 SELECT
5.1 SELECT list
5.2 DISTINCT
6 ORDER BY
7 TOP / OFFSET-FETCH
so ,in above steps ,group by will be executed in 3rd stage and your select will be executed in 5th stage..
This means your alias(which is in select stage) ,will be visible to operators following select (after 5),but not before them..
I would suggest taking a book which teaches basics well and i found Itzik Ben-Gan books to be extremely helpfull T-SQL Fundamentals Third Edition
You can try the following query and test to get your expected result.
DECLARE #SalesOrderHeader TABLE(SalesPersonID INT,SalesOrderID INT,OrderDate DATETIME)
INSERT INTO #SalesOrderHeader
SELECT 1,101,'20-Mar-2018' UNION ALL SELECT 1,102,'21-Mar-2018' UNION ALL SELECT 1,102,'21-Mar-2018' UNION ALL SELECT 2,202,'21-Mar-2018'
SELECT * FROM #SalesOrderHeader
SELECT SalesPersonID AS SalesPersonID, COUNT(SalesOrderID) NoOfOrder, YEAR(OrderDate) AS SalesYear
FROM #SalesOrderHeader
GROUP BY SalesPersonID,YEAR(OrderDate);
Thanks.
Related
I'm learning SQL, for an exercise I have to several things.
I'm making a query to compare the most recent orderdate with the orderdate before. I want to use a correlated subquery for this. I have already made it using a Cross Apply and Window functions.
At the moment I have this:
select
b1.klantnr,
DATEDIFF(D, (Select MAX(b1.Besteldatum)),
(Select MAX(b1.Besteldatum)
where besteldatum not in (Select MAX(b1.besteldatum)))) as verschil
from
bestelling b1
group by
b1.klantnr, b1.besteldatum
I only get null values in the datediff column. It should return this:
Results
I'm using SQL Server 2014 Management Studio.
Any help appreciated.
Here is one simple way:
select datediff(day, min(bs.Besteldatum), max(bs.Besteldatum)) as most_recent_diff
from (select top (2) bs.*
from bestelling bs
order by bs.Besteldatum
) bs;
This uses a subquery, but not a correlated subquery. Should have really good performance, if you have an index on bestselling(Besteldatum).
A correlated subquery way.
select top 1 bs.*,datediff(day,
(select max(bs1.Besteldatum)
from bestelling bs1
where bs1.Besteldatum<bs.Besteldatum),
bs.Besteldatum
) as diff
from bestelling bs
order by bs.Besteldatum desc
This gives only the difference between latest date and the date preceding it. If you need all records remove top 1 from the query.
I have query where there is COUNT(1) in select statement.
I want to know what does it return. COUNT(*) will return the number of rows but COUNT(1) I have no idea. I tried to execute one statement in DB2 but got error saying COLUMN OR EXPRESSION IN THE SELECT LIST IS NOT VALID.
Post your SQL statement.
I suspect you have something like
select customer, count(1)
from salesHistory
In which case, DB2 isn't complaining about count(1) which is perfectly valid; but it's complaining because you've got a aggregate function in the select list along with a non-aggregate column. In order to do that, you have to include a GROUP BY clause.
select customer, count(1)
from salesHistory
group by customer
I am trying to write a query to count every date in my database as you can see here :
SELECT
[SubmitDateTime],
COUNT(*)
FROM
[ParkingDB].[dbo].[Traffic]
GROUP BY
submitdatetime
The result is :
I think SQL Server is grouping my date based on date+time and it's my problem, but in fact I need to group them based on date. I use this type of query :
SELECT
[SubmitDateTime],
COUNT(*)
FROM
[ParkingDB].[dbo].[Traffic]
GROUP BY
CAST(myDateTime AS DATE)
But it doesn't work. I'm getting this error:
Msg 8120, Level 16, State 1, Line 3 Column
'ParkingDB.dbo.Traffic.SubmitDateTime' is invalid in the select list
because it is not contained in either an aggregate function or the
GROUP BY clause.
You also need to modify the columns in your SELECT statement:
SELECT
CAST([SubmitDateTime] AS DATE),
COUNT(*)
FROM [ParkingDB].[dbo].[Traffic]
GROUP BY
CAST([SubmitDateTime] AS DATE)
When using GROUP BY clause, all non-aggregated columns in the SELECT statement must appear in the GROUP BY clause.
Can you try the query below?
SELECT
CAST(myDateTime AS DATE) [SubmitDateTime],
COUNT(*)
FROM [ParkingDB].[dbo].[Traffic]
GROUP BY
CAST(myDateTime AS DATE)
We tried to transposing of data using unpivot operator in sql server 2012.same thing we have to output using postgres database. so,we have to rewrite given syntax into postgresql.
We have also tried on postgresql :
uncrosstab() function using given query structure.
select * from uncrosstab( select * from tablename) as ct()
ie Our input sql server 2012 syntax is :
select Name,budget,CASE WHEN bmon='BudMnt1' THEN CONVERT(DATE, '01-JAN-2015')
WHEN bmon='BudMnt2' THEN CONVERT(DATE, '01-FEB-2015')
WHEN bmon='BudMnt3' THEN CONVERT(DATE, '01-MAR-2015')
WHEN bmon='BudMnt4' THEN CONVERT(DATE, '01-APR-2015')
WHEN bmon='BudMnt5' THEN CONVERT(DATE, '01-MAY-2015')
WHEN bmon='BudMnt6' THEN CONVERT(DATE, '01-JUN-2015')
WHEN bmon='BudMnt7' THEN CONVERT(DATE, '01-JUL-2015')
WHEN bmon='BudMnt8' THEN CONVERT(DATE, '01-AUG-2015')
WHEN bmon='BudMnt9' THEN CONVERT(DATE, '01-SEP-2015')
WHEN bmon='BudMnt10' THEN CONVERT(DATE, '01-OCT-2015')
WHEN bmon='BudMnt11' THEN CONVERT(DATE, '01-NOV-2015')
WHEN bmon='BudMnt12' THEN CONVERT(DATE, '01-DEC-2015')
END AS bmon from tablename
UNPIVOT
(
budget
FOR bmon IN (BudMnt1,
BudMnt2,
BudMnt3,
BudMnt4,
BudMnt5,
BudMnt6,
BudMnt7,
BudMnt8,
BudMnt9,
BudMnt10,
BudMnt11,
BudMnt12)
) p
Any help would be much appreciated ?
PIVOT and UNPIVOT are non-ANSI standard SQL commands that I am not familiar with. I also don't have your full table definition so I am having a hard time just understanding your SQL. So, I turned to Microsoft's site and found an example to work with.
https://technet.microsoft.com/en-us/library/ms177410(v=sql.105).aspx
Using their UNPIVOT example, I came up with two solutions. First, let's create a table in Greenplum and insert some values.
CREATE TABLE pvt (VendorID int, Emp1 int, Emp2 int, Emp3 int, Emp4 int, Emp5 int)
distributed by (vendorid);
INSERT INTO pvt VALUES (1,4,3,5,4,4);
INSERT INTO pvt VALUES (2,4,1,5,5,5);
INSERT INTO pvt VALUES (3,4,3,5,4,4);
INSERT INTO pvt VALUES (4,4,2,5,5,4);
INSERT INTO pvt VALUES (5,5,1,5,5,5);
The unsupported Microsoft UNPIVOT example:
SELECT VendorID, Employee, Orders
FROM
(SELECT VendorID, Emp1, Emp2, Emp3, Emp4, Emp5
FROM pvt) p
UNPIVOT
(Orders FOR Employee IN
(Emp1, Emp2, Emp3, Emp4, Emp5)
)AS unpvt;
GO
Solution 1
select vendorid, 'emp1' as employee, emp1 from pvt
union all
select vendorid, 'emp2' as employee, emp2 from pvt
union all
select vendorid, 'emp3' as employee, emp3 from pvt
union all
select vendorid, 'emp4' as employee, emp4 from pvt
union all
select vendorid, 'emp5' as employee, emp5 from pvt;
This is simple and easy to write but each query is run sequentially. It also means you are scanning the pvt table 5 times but it might be the right solution for you.
Solution 2
select vendorid,
split_part(unpivot, ',', 1) as employee,
split_part(unpivot, ',', 2) as orders
from (
select vendorid, unnest(employee) as unpivot
from (
select vendorid,
array['emp1,' || emp1,
'emp2,' || emp2,
'emp3,' || emp3,
'emp4,' || emp4,
'emp5,' || emp5] as employee
from pvt
) as sub
) as sub2;
Solution 2 is a little "cooler" as it passes through the pvt table only once and converts the distinct columns into array elements. I concatenated the name of the column so I could have a index to each array element. I then used unnest to convert the array elements to rows. Finally, I used split_part to split each array index + value into separate columns. For fun, I called this "unpivot". :)
Lastly, I suggest you store the data so that is easy to use. That recommendation is valid for any database too. If you often want to see the data that is the result of UNPIVOT, store the data that way. Don't make analysis harder than it should be.
I am using SQL Server 2008 Enterprise. I am using the following statement in SQL Server Management Studio as a part of a store procedure, and there is following error (compile error when I press F5 to run the store procedure). But when I removed count(), all error disappears. Any ideas what is wrong with count()? Another question is, my purpose is to return the total number of matched result and only return a part of result to implement paging (using tt.rowNum between #startPos and #requireCount + #startPos-1), any ideas how to implement that?
SELECT *
FROM (SELECT count(*), t.id,t.AdditionalInfo, ROW_NUMBER()
OVER (order by t.id) AS rowNum
FROM dbo.foo t
CROSS APPLY t.AdditionalInfo.nodes('/AdditionalInfo')
AS MyTestXMLQuery(AdditionalInfo)
WHERE
(Tag4=''+#InputTag4+'' OR Tag5=''+#InputTag5+'')
and (MyTestXMLQuery.AdditionalInfo.value
('(Item[#Name="Tag1"]/#Value)[1]', 'varchar(50)')
LIKE '%'+#Query+'%'
or MyTestXMLQuery.AdditionalInfo.value
('(Item[#Name="Tag2"]/#Value)[1]', 'varchar(50)')
LIKE '%'+#Query+'%'
or MyTestXMLQuery.AdditionalInfo.value
('(Item[#Name="Tag3"]/#Value)[1]', 'varchar(50)')
LIKE '%'+#Query+'%') ) tt
WHERE tt.rowNum between #startPos and #requireCount + #startPos-1
Error message,
Column 'dbo.foo.ID' is invalid in the select list
because it is not contained in either an aggregate function
or the GROUP BY clause.
No column name was specified for column 1 of 'tt'.
thanks in advance,
George
Replace it with
SELECT count(*) over() AS [Count]
It needs an alias as it is a column in a derived table.
The empty over() clause will return the count in the whole derived table. Is that what you need?
You generally can't mix aggregate functions and normal field selections without a GROUP BY clause.
In queries where you are only selecting a COUNT(*) it assumes you mean to lump everything together in one group. Once you select another field (without a corresponding GROUP BY), you introduce a contradiction to that assumption and it will not execute.
You need to have a GROUP BY clause. Try this:
SELECT *
FROM (SELECT
count(*) AS c, t.id,t.AdditionalInfo
FROM
dbo.foo t
CROSS APPLY
t.AdditionalInfo.nodes('/AdditionalInfo') AS MyTestXMLQuery(AdditionalInfo)
WHERE
(Tag4=''+#InputTag4+'' OR Tag5=''+#InputTag5+'')
and (MyTestXMLQuery.AdditionalInfo.value('(Item[#Name="Tag1"]/#Value)[1]', 'varchar(50)') LIKE '%'+#Query+'%'
or MyTestXMLQuery.AdditionalInfo.value('(Item[#Name="Tag2"]/#Value)[1]', 'varchar(50)') LIKE '%'+#Query+'%'
or MyTestXMLQuery.AdditionalInfo.value('(Item[#Name="Tag3"]/#Value)[1]', 'varchar(50)') LIKE '%'+#Query+'%')
GROUP BY t.id,t.AdditionalInfo
) tt
WHERE tt.rowNum between #startPos and #requireCount + #startPos-1
There might be more. Not sure.
Either way, it would do you a lot of good to learn about the theory behind the relational database model. This query needs a lot more help than what I just added. I mean it needs A LOT more help.
Edit: You also can't have a ROW_NUMBER() in a query that selects COUNT(*). What would you be trying to number? The number of Counts?
A guess, cause I can't run it, but try Changing it to:
Select * From
(Select count(*), t.id, t.AdditionalInfo, ROW_NUMBER()
OVER (order by t.id) AS rowNum
From dbo.foo t
CROSS APPLY t.AdditionalInfo.nodes('/AdditionalInfo')
AS MyTestXMLQuery(AdditionalInfo)
Where
(Tag4=''+#InputTag4+'' OR Tag5=''+#InputTag5+'')
and (MyTestXMLQuery.AdditionalInfo.value
('(Item[#Name="Tag1"]/#Value)[1]', 'varchar(50)')
LIKE '%'+#Query+'%'
or MyTestXMLQuery.AdditionalInfo.value
('(Item[#Name="Tag2"]/#Value)[1]', 'varchar(50)')
LIKE '%'+#Query+'%'
or MyTestXMLQuery.AdditionalInfo.value
('(Item[#Name="Tag3"]/#Value)[1]', 'varchar(50)')
LIKE '%'+#Query+'%')
Group By t.id, t.AdditionalInfo ) tt
Where tt.rowNum between #startPos and #requireCount + #startPos-1