Column invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause - sql

We have a table which will capture the swipe record of each employee. I am trying to write a query to fetch the list of distinct employee record by the first swipe for today.
We are saving the swipe date info in datetime column. Here is my query its throwing exception.
select distinct
[employee number], [Employee First Name]
,[Employee Last Name]
,min([DateTime])
,[Card Number]
,[Reader Name]
,[Status]
,[Location]
from
[Interface].[dbo].[VwEmpSwipeDetail]
group by
[employee number]
where
[datetime] = CURDATE();
Getting error:
Column 'Interface.dbo.VwEmpSwipeDetail.Employee First Name' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Any help please?
Thanks in advance.

The error says it all:
...Employee First Name' is invalid in the select list because it is not contained
in either an aggregate function or the GROUP BY clause
Saying that, there are other columns that need attention too.
Either reduce the columns returned to only those needed or include the columns in your GROUP BY clause or add aggregate functions (MIN/MAX). Also, your WHERE clause should be placed before the GROUP BY.
Try:
select distinct [employee number]
,[Employee First Name]
,[Employee Last Name]
,min([DateTime])
,[Card Number]
,min([Reader Name])
from [Interface].[dbo].[VwEmpSwipeDetail]
where CAST([datetime] AS DATE)=CAST(GETDATE() AS DATE)
group by [employee number], [Employee First Name], [Employee Last Name], [Card Number]
I've removed status and location as this is likely to return non-distinct values. In order to return this data, you may need a subquery (or CTE) that first gets the unique IDs of the SwipeDetails table, and from this list you can join on to the other data, something like:
SELECT [employee number],[Employee First Name],[Employee Last Name].. -- other columns
FROM [YOUR_TABLE]
WHERE SwipeDetailID IN (SELECT MIN(SwipeDetailsId) as SwipeId
FROM SwipeDetailTable
WHERE CAST([datetime] AS DATE)=CAST(GETDATE() AS DATE)
GROUP BY [employee number])

Please Try Below Query :
select distinct [employee number],[Employee First Name]
,[Employee Last Name]
,min([DateTime])
,[Card Number]
,[Reader Name]
,[Status]
,[Location] from [Interface].[dbo].[VwEmpSwipeDetail] group by [employee number],[Employee First Name]
,[Employee Last Name]
,[Card Number]
,[Reader Name]
,[Status]
,[Location] having [datetime]=GetDate();

First find the first timestamp for each employee on the given day (CURDATE), then join back to the main table to get all the details:
WITH x AS (
SELECT [employee number], MIN([datetime] AS minDate
FROM [Interface].[dbo].[VwEmpSwipeDetail]
WHERE CAST([datetime] AS DATE) = CURDATE()
GROUP BY [employee number]
)
select [employee number]
,[Employee First Name]
,[Employee Last Name]
,[DateTime]
,[Card Number]
,[Reader Name]
,[Status]
,[Location]
from [Interface].[dbo].[VwEmpSwipeDetail] y
JOIN x ON (x.[employee number] = y.[employee number] AND x.[minDate] =Y.[datetime]

This should not be marked as mysql as this would not happen in mysql.
sql-server does not know which of the grouped [Employee First Name] values to return so you need to add an aggregate (even if you only actually expect one result). min/max will both work in that case. The same would apply to all the other rows where they are not in the GROUP BY or have an aggregate function (EG min) around them.

Related

Selecting values only for last day of month

I have a query that's supposed to grab only the value for the last day of the month from all my existing records (so the last day of multiple months). I'm unable to get the value I'm needing for ONLY the last day, due to using a SUM() clause. This is adding all the values for the whole month together. Can I get only the value for the last day another way? Is there something I'm missing?
Code so far:
SELECT
ID,
[Customer Name],
Year([ValDate]) & IIf(Len(Month([ValDate]))>1,Month([ValDate]),"0" & Month([ValDate])) AS BalMonth,
Sum(Value) AS LastValue
FROM
Archive
GROUP BY
ID,
[Customer Name],
Year([ValDate]),
Month([ValDate])
ORDER BY
ID,
Year(ValDate) & Month(ValDate)
Other Code tested:
SELECT
ID,
[Customer Name],
YEAR([ValDate]) & MONTH([ValDate]) & MAX(DAY([BalDate])) AS LastDayofMonth
FROM
Archive
GROUP BY
ID ,
[Customer Name],
YEAR([ValDate]),
MONTH([ValDate])
ORDER BY
ID,
[Customer Name],
YEAR([ValDate]),
MONTH([ValDate])
The second section of code didn't work as it produces the dates in YYYYMMDD format. This makes it so it doesn't allow proper ordering of the dates. Instead, the dates are being ordered as 1 , 10 , 11 , 12 , 2 , 3 , 4 , etc.
If anything is unclear I'll try my best to clarify, just let me know!
Try something like:
SELECT
ID,
[Customer Name],
[ValDate] AS LastDayofMonth,
Sum([FieldToSum]) As Total
FROM
Archive
GROUP BY
ID,
[Customer Name],
[ValDate]
HAVING
[ValDate] = DateSerial(Year([ValDate]), Month([ValDate]) + 1, 0)
Edit:
To have a formatted date output, try this:
SELECT
ID,
[Customer Name],
Format([ValDate], "yyyymmdd") AS LastDayofMonth,
Sum([FieldToSum]) As Total
FROM
Archive
WHERE
[ValDate] = DateSerial(Year([ValDate]), Month([ValDate]) + 1, 0)
GROUP BY
ID,
[Customer Name],
Format([ValDate], "yyyymmdd")

Extract a specific line from a SELECT statement based on the last Trasanction date

Good day,
I have an SQL code that return to me all quantities that I received over time, but I want to display only the latest one
SELECT * FROM
(SELECT DISTINCT
[dbo].[ttcibd001110].[t_cmnf] AS [Manufacturer],
[dbo].[ttcibd001110].[t_item] AS [Item code],
[dbo].[ttcibd001110].[t_dsca] AS [Description],
[dbo].[ttcibd001110].[t_seak] AS [Search key 1],
[dbo].[twhinr110110].[t_trdt] AS [Transaction date],
[dbo].[twhinr110110].[t_cwar] AS [Warehouse],
[dbo].[twhinr110110].[t_qstk] AS [Quantity Inventory Unit]
FROM [dbo].[twhinr110110] LEFT JOIN [dbo].[ttcibd001110]
ON [dbo].[twhinr110110].[t_item]=[dbo].[ttcibd001110].[t_item]
WHERE [dbo].[twhinr110110].[t_koor]='2' AND [dbo].[ttcibd001110].[t_cmnf]='ManufacturerX') AS tabel
WHERE ltrim(tabel.[Item code])='1000045'
Now, from this selection I want to select only the line with the latest Transaction date, but I am stuck.
Can somebody help me in this way?
Thank you!
Change your beginning to
SELECT TOP 1
and after where use
ORDER BY [Transaction date] DESC

sql distinct with multiple fields requried

I'm using Advantage Database Server by Sybase. I need to elimiate duplicate addbatch's from my report, but having trouble pulling up just distinct records. Any idea what I am missing?
here is what I am using
SELECT DISTINCT
SI.[addbatch] as [Batch#],
SI.[current account #] as [Account],
SI.[status date] as [Status Date],
SI.[SKU] as [SKU],
AC.[email address] as [Email]
FROM salesinventory SI, accounts AC
WHERE AC.[account #]=SI.[current account #] and [Status Date] > '6/1/2015'
I still get duplicate addbatch's though. I'm not sure where I am going wrong! Thanks in advance! Wasn't even sure how to google this question!
The problem is that you need to check uniqueness of a single column and that's not actually what your code is performing. Try this
SELECT *
FROM (SELECT SI.[addbatch] as [Batch#],
SI.[current account #] as [Account],
SI.[status date] as [Status Date],
ETC,
ROW_NUMBER() OVER (PARTITION BY [Batch#]) AS RowNumber
FROM salesinventory SI, accounts AC
WHERE AC.[account #]=SI.[current account #] and [Status Date] > '6/1/2015') as rec
WHERE rec.RowNumber = 1
-- The following code is generic to de-duplicate records, modify to suit your need.
select x.[Well_Name] as nameX
, x.[TestDate] as dateX
from (
SELECT count(*) as dup
,[Well_Name]
,[TestDate]enter code here
FROM [dbo].[WellTests]
group by [TestDate] ,[Well_Name] ) x
where dup > 1
If you want to have unique batch numbers in your result, you have to GROUP BY the batch field only.
Something like this should work:
SELECT
SI.[addbatch] as [Batch#],
MIN(SI.[current account #]) as [Account],
MIN(SI.[status date]) as [Status Date],
MIN(SI.[SKU]) as [SKU],
MIN(AC.[email address]) as [Email]
FROM salesinventory SI, accounts AC
WHERE AC.[account #]=SI.[current account #] and [Status Date] > '6/1/2015'
GROUP BY
SI.[addbatch]
You didn't say how you want to aggregate the other columns, just replace MIN with something that makes more sense for you, like SUM or COUNT, etc.
There is a topic about grouping in the documentation.
PS: SELECT DISTINCT is (basically) just a shorter way to GROUP BY on all columns without any aggregation.

how to select columns with aggregate function sql server

i need to select two columns.1. calculate sum of one column and display it 2.display column as it is. so i tried below code
SELECT Sum(CONVERT(FLOAT, Replace(total, Char(0), ''))) AS Total,
[product name]
FROM tb_sales_entry_each_product
GROUP BY [sales date]
error message
Column 'tb_sales_entry_each_product.Product Name' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
where i made error.thanks
just need to group
select SUM(CONVERT(float, REPLACE(Total, CHAR(0), ''))) as Total, [Product Name]
from tb_sales_entry_each_product group by [Sales Date], [product name]
When ever you do a numercial count sum etc, any other columns need to be grouped.
thats all your missing
Try this:
select SUM(CONVERT(float, REPLACE(Total, CHAR(0), ''))) as Total,
[Product Name] ,[Sales Date]
from tb_sales_entry_each_product
group by [Sales Date],[Product Name]

SQL aggregate and other fields showing in query

I have a query, where I need the MIN of a DateTime field and then I need the value of a corresponding field in the same row.
Now, I have something like this, however I cannot get Price field without putting it also in an aggregate clause, which is not what I want.
SELECT MIN([Registration Time]), Price FROM MyData WHERE [Product Series] = 'XXXXX'
I need the MIN of the Registration Time field and then I just want the corresponding Price field for that row, however how do I show that?
I do also need my WHERE clause as shown.
I'm sure I've overlooked something really obvious. Using SQL Server 2008
If you want just one record with [Registration Time], Price, it'd be as simple as this:
select top 1 [Registration Time], Price
from MyData
where [Product Series] = 'XXXXX'
order by [Registration Time]
If you want minimum [Registration Time] and corresponding Price for all [Product Series], then there's a few approaches, for example, using row_number() function:
with cte as (
select
[Registration Time], Price,
row_number() over(partition by [Product Series] order by [Registration Time]) as rn
from MyData
)
select
[Registration Time], Price, [Product Series]
where rn = 1