Turning results in comma separated list - sql

I'm using this code to get the following results:
Select [Doc #],
[Production Number]
From vwLiveDocuments
Where [production number] IN
(
SELECT [production number]
FROM vwLiveDocuments
where [tags] LIKE N'%name of tag%'
Group by [production number]
Having Count (*) > 1
)
I'll get the following results:
'Doc #' 'Production number'
117611 CGI00069441
47864 CGI00069441
47865 CGI00069457
117901 CGI00069457
47866 CGI00069460
117904 CGI00069460
121479 CGI00071490
53934 CGI00071490
You can see duplicate results in Production number. what i would like is to convert this list to get the following results:
'Production number' 'Doc #'
CGI00069441 117611,47864
CGI00069457 47865,117901
CGI00069460 47866,117904
CGI00071490 121479,53934
Where for every duplicate "Prod number" i would like to get a comma seperate list of the doc # that are duplicates.

Use For xml path() trick to do this.
;WITH cte
AS (SELECT [Doc #],
[Production Number]
FROM vwLiveDocuments
WHERE [production number] IN (SELECT [production number]
FROM vwLiveDocuments
WHERE [tags] LIKE N'%20150126-Appendix B%'
GROUP BY [production number]
HAVING Count (*) > 1))
SELECT [Production number],
Stuff((SELECT ',' + CONVERT(VARCHAR(10), [doc #])
FROM cte b
WHERE b.[Production number] = a.[Production number]
FOR xml path('')), 1, 1, '') [Doc #]
FROM cte a
GROUP BY [Production number]
ORDER BY [Production Number] ASC

Related

Recursive CTE increases time

I just made this code, the My_View table has about 9,000 rows, the CTE one has about 14,000. And CTE's first iteration lasted about 0,5s (Handwritting the code), but with the recursion, it lasts about 5 min. The main problem should be at the recursive code, but it shouldn't.
The objective of the code is: Having the following data:
{ID} [Primary ID] [Secondary ID]
Where all the Primary ID's begin with C... And the Secondary ID's with K... The problem is that some Secondary ID's are a link to a Primary ID as following:
{ID} [C010] [K011]
{ID} [C020] [C010]
{ID} [C020] [K020]
So what I want is it to finish like:
{ID} [C010] [K011]
{ID} [C020] [K011]
{ID} [C020] [K020]
{ID} = {[Cod_ 1], [First year], [First month]}
WITH CTE AS ( SELECT DISTINCT [Cod_ 1], [First year], [First month], [Primary ID], [Secondary ID] FROM My_View WHERE [Secondary ID] LIKE 'K%'
UNION ALL
SELECT m1.[Cod_ 1], m1.[First year], m1.[First month], m1.[Primary ID], [m2.Secondary ID] FROM My_View m1 INNER JOIN CTE m2 ON m1.[Cod_ 1] = m2.[Cod_ 1] AND m1.[First year] = m2.[First year] AND m1.[First month] = m2.[First month] AND m1.[Secondary ID] = m2.[Primary ID]
)
SELECT DISTINCT *
FROM CTE
ORDER BY [Cod_ 1], [Primary ID], [Secondary ID]
I believe you need to add WHERE condition like
WHERE m1.[Primary ID] NOT LIKE 'K%'
to avoid recursion-depth error or any similar case may slow it.
So this may help you:
WITH CTE
AS (
SELECT DISTINCT [Cod_ 1]
,[First year]
,[First month]
,[Primary ID]
,[Secondary ID]
FROM My_View
WHERE [Secondary ID] LIKE 'K%'
UNION ALL
SELECT m1.[Cod_ 1]
,m1.[First year]
,m1.[First month]
,m1.[Primary ID]
,[m2.Secondary ID]
FROM My_View m1
INNER JOIN CTE m2 ON m1.[Cod_ 1] = m2.[Cod_ 1]
AND m1.[First year] = m2.[First year]
AND m1.[First month] = m2.[First month]
AND m1.[Secondary ID] = m2.[Primary ID]
WHERE m1.[Primary ID] NOT LIKE 'K%'
)
SELECT DISTINCT *
FROM CTE
ORDER BY [Cod_ 1]
,[Primary ID]
,[Secondary ID]

Workaround for PIVOT statement

I have this query, is taking like 2 minutes to resolve, I need to find a workaround, I know that UNPIVOT has a better solution using CROSS APPLY, is there anything similar for PIVOT?
SELECT [RowId], [invoice date], [GL], [Entité], [001], [Loc], [Centre Cout], [Compte_1], [Interco_1], [Futur_1], [Department], [Division], [Compagnie], [Localisation], [Centre/Cout], [Compte], [Interco], [Futur], [Account], [Mobile], [Last Name], [First Name], [license fee], [GST], [HST], [PST], [Foreign Tax], [Sales Tax License], [Net Total], [Total], [ServiceType], [Oracle Cost Center], [CTRL], [EXPENSE], [Province]
FROM
(SELECT fd.[RowId], fc.[ColumnName], fd.[Value]
FROM dbo.FileData fd
INNER JOIN dbo.[FileColumn] fc
ON fc.[FileColumnId] = fd.[FileColumnId]
WHERE FileId = 1
AND TenantId = 1) x
PIVOT
(
MAX(Value)
FOR [ColumnName] IN ( [invoice date], [GL], [Entité], [001], [Loc], [Centre Cout], [Compte_1], [Interco_1], [Futur_1], [Department], [Division], [Compagnie], [Localisation], [Centre/Cout], [Compte], [Interco], [Futur], [Account], [Mobile], [Last Name], [First Name], [license fee], [GST], [HST], [PST], [Foreign Tax], [Sales Tax License], [Net Total], [Total], [ServiceType], [Oracle Cost Center], [CTRL], [EXPENSE], [Province])
) AS p
Pivots are great, but so are Conditional Aggregations. Also, there would be no datatype conficts or conversions necessary
SELECT [RowId]
,[invoice date] = max(case when [FileColumnId] = ??? then Value end)
,[GL] = max(case when [FileColumnId] = ??? then Value end)
,... more fields
FROM dbo.FileData fd
WHERE FileId = 1
AND TenantId = 1
Group By [RowId]
EDIT
You could add back the join to make it more readable.

SQL Sub-query (Where In)

I get an error with my sub-query and am not seeing what I am doing wrong. Sub-query works on it's on. There Where-In is obviously what is the problem. Also tried EXISTS.
select [ID NUMBER], [PERNO], [TITLE], [INITIALS], [SURNAME], [DATE OF BIRTH]
from dbo.[DATASEPT002]
WHERE [ID NUMBER] IN
( SELECT [ID NUMBER], COUNT([PERSALNO]) AS COUNTOF
FROM [dbo].[DATASEPT]
GROUP BY [ID NUMBER] HAVING COUNT([PERSALNO]) >1 )
You have two columns in the subquery. Only one can be used for the IN comparison:
select [ID NUMBER], [PERNO], [TITLE], [INITIALS], [SURNAME], [DATE OF BIRTH]
from dbo.[DATASEPT002] t
WHERE [ID NUMBER] IN (SELECT [ID NUMBER]
FROM [dbo].[DATASEPT]
GROUP BY [ID NUMBER]
HAVING COUNT([PERSALNO]) > 1
);
However, I would expression this more typically using window functions:
select t.*
from (select t.*, count(*) over (partition by persalno) as cnt
from DATASEPT002 t
) t
where cnt > 1;

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

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.

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]