I can't figure out the issue with my UNION query - sql

This is what I'm using:
SELECT [Contact ID], [Contact], [Zip Code], [County]
FROM [Training WLS]
UNION
SELECT [Contact ID], [Contact], [Zip Code], [County]
FROM [WLS TA]
This is the error:
Syntax error(missing operator) in query expression 'Contact ID'.

My guess? The engine's not smart enough to Union columns that have spaces in the names.
Try this instead, and see if it works:
SELECT [Contact ID] as ContactID, [Contact], [Zip Code] as ZipCode, [County]
FROM [Training WLS]
UNION
SELECT [Contact ID] as ContactID, [Contact], [Zip Code] as ZipCode, [County]
FROM [WLS TA]

Related

How can I know the exact column name and value on which the conversion failed while running an SQL query?

I got below error while running a SQL query:
Msg 241, Level 16, State 1, Line 16
Conversion failed when converting date and/or time from character string.
I tried putting it Line by Line so that the error would point out the exact line and it did.
But to my surprise a date / time conversion error was given and pointed to a field which is varchar. In this example it pointed out to 'F1' as Facility field which is the first line of the query.
SELECT 'F1' AS FACILITY, NULL AS NSH, NULL AS EMC, NULL AS OD, NULL AS OA,
URN AS PA,
Title, [First Name], [Second Name], [Third Name], [Family Name], Sex, [Date Of Birth],
[Estimated Date Of Birth ], [Marital Status],
Religion, [Nationality Code],
Nationality, [Passport Number], [Country Of Birth], [Preferred Language],
Address, [PO Box], CONVERT(VARCHAR(15), [Home Phone]) AS [Home Phone], [Office Phone], [Mobile Phone], [Blood Type], VIP, Notes, [National ID], NULL AS [Deceased Date], NULL AS [Deceased Time],
NULL AS [Deceased Indicator (Y/N)], NULL AS [Location Of Death], NULL AS [Death Notified By]
FROM PD_PA
UNION ALL
SELECT 'F2' AS FACILITY, URN AS NSH, NULL AS EMC, NULL AS OD, NULL AS OA, NULL AS PA, Title, [First Name], [Second Name], [Third Name], [Family Name], Sex, BDATE AS [Date Of Birth], [Estimated Date Of Birth], [Marital Status], Religion, [NationalityCode],
Nationality, [Passport Number], [Country], [Preferred Language],
Address, [PO Box], CONVERT(VARCHAR(15), [Home Phone]) AS [Home Phone], [Office Phone], [Mobile Phone] AS [MobilePhone], [Blood Type], VIP, Notes, [National ID], NULL AS [Deceased Date], NULL AS [Deceased Time],
NULL AS [Deceased Indicator (Y/N)], NULL AS [Location Of Death], NULL AS [Death Notified By]
FROM PD_LKIL
Is there a way to trace or know the details of which is the exact field and on which value exactly is the error thrown?
Since my data has over 100k entries, its difficult to trace out and proceed.
If you are on a version greater than 2008 you can replace your CONVERT with TRY_CONVERT.
This returns null if the conversion fails so you can simply check for NULLs in the output.

SQL using count in case statement

I'm trying to group all activity where the count is less than 5 (for data sharing reasons).
The ID Code and ID Name give me high level numbers, but as soon as I include "shop code" I get some low level numbers for customers that go to odd shops once or twice.
Select Count(*) [Activity],
T.[ID Code],
T.[ID Name],
Case when Count(*) < 6 then 'Other Shop' Else T.Shop End [Shop Code]
From MyTable T
Group By T.[ID Code],
T.[ID Name],
Case when Count(*) < 6 then 'Other Shop' Else T.Shop End
But obviously I can't use a count in a case statement. I've tried some of the solutions to similar questions but none of them work!
Thanks
The problem is the GROUP BY:
Select Count(*) as [Activity],
T.[ID Code],
T.[ID Name],
(Case when Count(*) < 6 then 'Other Shop' Else T.Shop
End) as [Shop Code]
From MyTable T
Group By T.[ID Code],
T.[ID Name];
Aggregate functions (or expressions with aggregates) don't belong in the GROUP BY. These are calculated in the SELECT, not used to define groups.
You can use the HAVING and UNION ALL statement, like this:
Select Count(*) as [Activity],
T.[ID Code],
T.[ID Name],
'Other Shop' [Shop Code]
From MyTable T
Group By T.[ID Code],
T.[ID Name]
having Count(*) < 6
union all
Select Count(*) as [Activity],
T.[ID Code],
T.[ID Name],
T.Shop [Shop Code]
From MyTable T
Group By T.[ID Code],
T.[ID Name]
having Count(*) >= 6
select
count(*) as activity,
code,
name,
Case when Count(*) < 6 then 'Other Shop' Else shopcode End as shopcode
from mytable group by code, name ,shopcode
The example below is a test in SQL Server.
It uses a window function for count, to change the Shop code.
And then groups it all, including that modified shopcode.
declare #ShopTable table ([ID Code] varchar(30), [ID Name] varchar(30), Shop varchar(30));
insert into #ShopTable ([ID Code], [ID Name], Shop) values
('S1','Shop 1','AA'),
('S1','Shop 1','BB'),
('S1','Shop 1','BB'),
('S1','Shop 1','CC'),
('S1','Shop 1','CC'),
('S1','Shop 1','CC'),
('S2','Shop 2','XX'),
('S2','Shop 2','YY');
select
count(*) as [Activity],
[ID Code],
[ID Name],
[Shop Code]
from (
select
[ID Code],
[ID Name],
case when count(*) over (partition by [ID Code], [ID Name]) < 6 then 'Other Shop' else Shop end as [Shop Code]
from #ShopTable
) Q
group by [ID Code], [ID Name], [Shop Code];

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.

Access 2007 Error 3071 -report using parameters

I have a query in MS Access 2007 that pulls data from two different tables and displays in a report. This occurs after a user clicks a button on the main form, which opens a date field parameter form where the user can select two dates. From there the query runs using the two dates the user provided, or the dates are 'faked' if none are selected to fill in the dates. I'm getting a Run-time error 3071, this expression is typed incorrectly, or it is too complex to be evaluated and i'm not sure why.
I run a similar query in another database and it executes perfectly so i'm at a loss.
Query is below,
(SELECT
[Group Name],
tbGroups AS [Group Number],
Analyst,
[Account Manager],
NULL AS [SER Number],
[Received Date] AS [Corporate Recevied],
DateValue(Created) AS [Sales Submitted],
tbBAAcceptedDate AS [BA Accepted],
NULL AS [Submitted to MDSS],
NULL AS [Completed],
NULL AS [Cancelled],
DateDiff("d",[Received Date], IIf([Forms]![frmReportDateFilter].[tbToDate] = '01/01/2116', Date(), CDate([Forms]![frmReportDateFilter].[tbToDate]))) AS [Aging Days Count],
LocalID AS [ID Number]
FROM ChangeRequest
WHERE DateValue([Created]) BETWEEN CDate([Forms]![frmReportDateFilter].[tbFromDate]) AND CDate([Forms]![frmReportDateFilter].[tbToDate]))
UNION ALL (SELECT
tbGroupProgramProductName AS [Group Name],
tbGroups AS [Group Number],
cboAnalyst AS Analyst,
tbAccountManager AS [Account Manager],
tbSERNumber AS [SER Number],
tbCorpReceivedDate AS [Corporate Recevied],
tbBAReceivedDate AS [Sales Submitted],
IIf([tbBAAcceptedDate] > CDate([Forms]![frmReportDateFilter].[tbToDate]), NULL, [tbBAAcceptedDate]) AS [BA Accepted],
IIf([tbSubmittedToMDSS] > CDate([Forms]![frmReportDateFilter].[tbToDate]), NULL, [tbSubmittedToMDSS]) AS [Submitted to MDSS],
DateValue(tbCompleteDate) AS [Completed],
DateValue(tbCancelDate) AS [Cancelled],
DateDiff("d",tbCorpReceivedDate, IIf([Forms]![frmReportDateFilter].[tbToDate] = '01/01/2116', Date(), CDate([Forms]![frmReportDateFilter].[tbToDate]))) AS [Aging Days Count],
LocalID AS [ID Number]
FROM tblDD
WHERE DateValue([tbBAReceivedDate]) BETWEEN CDate([Forms]![frmReportDateFilter].[tbFromDate]) AND CDate([Forms]![frmReportDateFilter].[tbToDate]))
ORDER BY [Group Name];
Any help is greatly appreciated.
Specify the control as Date. Something like this with no CDate - and no outer parenthesis:
PARAMETERS
[Forms]![frmReportDateFilter].[tbFromDate] Date,
[Forms]![frmReportDateFilter].[tbToDate] Date;
SELECT
[Group Name],
tbGroups AS [Group Number],
Analyst,
[Account Manager],
NULL AS [SER Number],
[Received Date] AS [Corporate Recevied],
DateValue(Created) AS [Sales Submitted],
tbBAAcceptedDate AS [BA Accepted],
NULL AS [Submitted to MDSS],
NULL AS [Completed],
NULL AS [Cancelled],
DateDiff("d",[Received Date], IIf([Forms]![frmReportDateFilter].[tbToDate] = #01/01/2116#, Date(), [Forms]![frmReportDateFilter].[tbToDate])) AS [Aging Days Count],
LocalID AS [ID Number]
FROM ChangeRequest
WHERE DateValue([Created]) BETWEEN [Forms]![frmReportDateFilter].[tbFromDate] AND [Forms]![frmReportDateFilter].[tbToDate]
UNION ALL
SELECT
tbGroupProgramProductName AS [Group Name],
tbGroups AS [Group Number],
cboAnalyst AS Analyst,
tbAccountManager AS [Account Manager],
tbSERNumber AS [SER Number],
tbCorpReceivedDate AS [Corporate Recevied],
tbBAReceivedDate AS [Sales Submitted],
IIf([tbBAAcceptedDate] > [Forms]![frmReportDateFilter].[tbToDate], NULL, [tbBAAcceptedDate]) AS [BA Accepted],
IIf([tbSubmittedToMDSS] > [Forms]![frmReportDateFilter].[tbToDate], NULL, [tbSubmittedToMDSS]) AS [Submitted to MDSS],
DateValue(tbCompleteDate) AS [Completed],
DateValue(tbCancelDate) AS [Cancelled],
DateDiff("d",tbCorpReceivedDate, IIf([Forms]![frmReportDateFilter].[tbToDate] = #01/01/2116#, Date(), [Forms]![frmReportDateFilter].[tbToDate])) AS [Aging Days Count],
LocalID AS [ID Number]
FROM tblDD
WHERE DateValue([tbBAReceivedDate]) BETWEEN [Forms]![frmReportDateFilter].[tbFromDate] AND [Forms]![frmReportDateFilter].[tbToDate]
ORDER BY [Group Name];

T-SQL [UNION ALL] removing records from query result

Have a simple UNION ALL query marrying the results of two queries. The first query, run independently, returns 1208 records and the second 14. I would expect a properly syntaxed UNION ALL to return 1222 records but mine falls to 896.
Makes zero sense to me:
SELECT a.WBS_ELEMENT_ID as [WBS Element],
a.WBS_ELEMENT_DESC as [WBS Element Desc],
a.UHC_INDUSTRY as [Industry],
a.UHC_SECTOR as [Sector],
a.UHC_DUNS_NUMBER as [UHC DUNS Number],
a.UHC_DUNS_NAME as [UHC DUNS Name],
a.PRIORITY_SUB_SECTOR as [Priority Sub Sector],
a.BUDGET_ALLOCATION as [Budget Allocation],
a.LAST_UPDATED_ON as [Last Updated]
FROM DimSectorPd a
WHERE a.wbs_element_id is not null
UNION ALL
SELECT ROW_NUMBER() OVER (ORDER BY a.wbs_element_desc) as [WBS Element],
a.WBS_ELEMENT_DESC as [WBS Element name],
a.UHC_INDUSTRY as [Industry],
a.UHC_SECTOR as [Sector],
a.UHC_DUNS_NUMBER as [UHC DUNS Number],
a.UHC_DUNS_NAME as [UHC DUNS Name],
a.PRIORITY_SUB_SECTOR as [Priority Sub Sector],
a.BUDGET_ALLOCATION as [Budget Allocation],
a.LAST_UPDATED_ON as [Last Updated]
from dimsectorpd a where a.WBS_ELEMENT_ID is null
Your queries should return all rows in the table. Unless the table changes between executions, the results from running the subqueries separately should be the same as from running them with the UNION ALL.
As a note, if you want to simplify the query, then you can do:
SELECT COALESCE(a.WBS_ELEMENT_ID,
ROW_NUMBER() OVER (PARTITION BY wbs_element_id ORDER BY a. wbs_element_desc)
) as [WBS Element],
a.WBS_ELEMENT_DESC as [WBS Element Desc],
a.UHC_INDUSTRY as [Industry],
a.UHC_SECTOR as [Sector],
a.UHC_DUNS_NUMBER as [UHC DUNS Number],
a.UHC_DUNS_NAME as [UHC DUNS Name],
a.PRIORITY_SUB_SECTOR as [Priority Sub Sector],
a.BUDGET_ALLOCATION as [Budget Allocation],
a.LAST_UPDATED_ON as [Last Updated]
FROM DimSectorPd a;
Obviously there is nothing wrong with your syntax, but if you want to try a different approach to getting your UNION ALL to work with ROW_NUMBER. Here it is:
;WITH q1
AS (
SELECT a.WBS_ELEMENT_ID AS [WBS Element]
,a.WBS_ELEMENT_DESC AS [WBS Element Desc]
,a.UHC_INDUSTRY AS [Industry]
,a.UHC_SECTOR AS [Sector]
,a.UHC_DUNS_NUMBER AS [UHC DUNS Number]
,a.UHC_DUNS_NAME AS [UHC DUNS Name]
,a.PRIORITY_SUB_SECTOR AS [Priority Sub Sector]
,a.BUDGET_ALLOCATION AS [Budget Allocation]
,a.LAST_UPDATED_ON AS [Last Updated]
FROM DimSectorPd a
WHERE a.wbs_element_id IS NOT NULL
UNION ALL
SELECT b.WBS_ELEMENT_ID AS [WBS Element] --just bring NULL values
,b.WBS_ELEMENT_DESC AS [WBS Element name]
,b.UHC_INDUSTRY AS [Industry]
,b.UHC_SECTOR AS [Sector]
,b.UHC_DUNS_NUMBER AS [UHC DUNS Number]
,b.UHC_DUNS_NAME AS [UHC DUNS Name]
,b.PRIORITY_SUB_SECTOR AS [Priority Sub Sector]
,b.BUDGET_ALLOCATION AS [Budget Allocation]
,b.LAST_UPDATED_ON AS [Last Updated]
FROM dimsectorpd b
WHERE b.WBS_ELEMENT_ID IS NULL
)
SELECT CASE
WHEN q1.[WBS Element] IS NULL
THEN ROW_NUMBER() OVER (ORDER BY q1.WBS_Element_Desc)
ELSE q1.[WBS Element]
END [WBS_Element]
,q1.[WBS Element Desc]
,q1.Industry
,q1.Sector
,q1.[UHC DUNS Number]
,q1.[UHC DUNS Name]
,q1.[Priority Sub Sector]
,q1.[Budget Allocation]
,q1.[Last Updated]
FROM q1
Here is a simplified example can you see if it works on your server?
SELECT a.low AS [My ID],
a.name AS [My Letter]
FROM master..spt_values as a
WHERE low is not null
UNION ALL
SELECT ROW_NUMBER() OVER (ORDER BY a.name) AS [My ID],
a.name AS [My Letter]
FROM master..spt_values as a
WHERE a.low is null
master..spt_values as 2515 rows on my system...