Insert value only when column is null - sql

I have 2 different Excel sources
Employee Excel source
Sales Excel source
In my employee source I have multiple folder and in my sales source I have multiple folders as well as multiple sheets, so I had to use two data flow task and two for each loop containers for that purpose.
I need to take the ID column from my employee Excel source, if the ID column in my employee source is not available (null) only if not available in my employee source then I need to get the ID Column from my sales source, they have matching SSN, how can I achieve this?
This is my staging table
SELECT
ID, [SSN],
[Borrower FirstName], [Borrower LastName],
[Borrower Email], [Home Phone], [Cell Phone],
[Marital Status], [Date of Birth],
[Current Street Address], [City], [State], [Zip],
[YearsAtThisAddress], [Sex], [Ethnicity], [Race]
FROM
[Mortgage]
This is my staging table, half of my data from the employee and half from sales.
Employee source has
[ID] ,[SSN] ,[Borrower FirstName] ,[Borrower LastName] ,[Borrower Email] ,[Home Phone] ,[Cell Phone] ,[Marital Status] ,[Date of Birth] ,[YearsAtThisAddress]
and SALES source has
[ID] ,[SSN] ,[Borrower FirstName] ,[Borrower LastName] ,[Borrower Email] ,[Home Phone] ,[Cell Phone] ,[Current Street Address] ,[City] ,[State] ,[Zip]

You have records from two data sources merged together and part of your requirement is to know from which source the record came (whether the ID column is NULL only if from the employee source). Our only clue as to whether a record came from the "employee source" is if there are values in the columns that differ between the two ([Marital Status], [Date of Birth], [YearsAtThisAddress]), but you don't say if any of these nullable, so we must make an assumption. Assuming the value in column [YearsAtThisAddress] can be used to determine the record's source (NOT NULL means "Employee" while NULL means "Sales"), you could do something like this to return the corresponding "Sales" ID number for records matching on SSN when the "Employee" ID number is NULL.
SELECT
CASE WHEN ID IS NULL AND [YearsAtThisAddress] IS NOT NULL
THEN (SELECT TOP (1) ID
FROM [Mortgage]
WHERE [YearsAtThisAddress] IS NULL
AND ID IS NOT NULL
AND [SSN] = m.[SSN]
ORDER BY ID)
ELSE ID
END AS ID,
[SSN],
[Borrower FirstName], [Borrower LastName],
[Borrower Email], [Home Phone], [Cell Phone],
[Marital Status], [Date of Birth],
[Current Street Address], [City], [State], [Zip],
[YearsAtThisAddress], [Sex], [Ethnicity], [Race]
FROM
[Mortgage] AS m

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.

Show Only Department Changes in Access 2010 Query

I have a table in Access that shows department history for associates; in total, there are several thousand records, and if an employee was in more than one department, he/she will have more than one record. An sample of the data is shown in the attached photo. Sample Table
The goal is for the query in Access to return transfer history for an associate, or in other words, the first time he/she was in each unique department code. An example of the expected outcome from the sample data is shown in the attached photo as well. Expected Outcome
Notice, for example, that the first associate (Employee Test1) had a top of stack row on 7/5/2016 that I would expect to be omitted because the previous record already reflects the transfer into 001271 on 5/2/2016.
Thus far, I've created the following query in Access via the Query Wizard (I'm a novice at SQL):
SELECT DISTINCT [Multiple Records_1].[Associate ID], [Multiple Records_1].[First Name], [Multiple Records_1].[Last Name], Min([Multiple Records_1].[Position Effective Date]) AS [MinOfPosition Effective Date], [Multiple Records_1].[Home Department Code], [Multiple Records_1].[Business Unit Description]
FROM [Multiple Records] INNER JOIN [Multiple Records] AS [Multiple Records_1] ON [Multiple Records].[Associate ID] = [Multiple Records_1].[Associate ID]
GROUP BY [Multiple Records_1].[Associate ID], [Multiple Records_1].[First Name], [Multiple Records_1].[Last Name], [Multiple Records_1].[Home Department Code], [Multiple Records_1].[Business Unit Description], [Multiple Records].[Home Department Code]
HAVING ((([Multiple Records].[Home Department Code])<>[Multiple Records_1].[Home Department Code]));
This got me pretty close to what I needed, but the 10/5/2015 record for "Employee Test 1" was suppressed because he transferred back into 001289...I want to make sure that similar records aren't dropped because an associate transfers out of a department but then later transfers back into it.
I would greatly appreciate any help! Many thanks in advance!
There are probably more elegant ways to solve this but this worked for me:
First create a summary (qryMin1) of the earliest overall date for each dpt. This gives the same result as your query, without joining the table to itself.
SELECT [Multiple Records].[Associate ID], Min([Multiple Records].[Position Effective Date]) AS EarliestEffectiveDate, [Multiple Records].[Home Department Code]
FROM [Multiple Records]
GROUP BY [Multiple Records].[Associate ID], [Multiple Records].[Home Department Code];
Now get any other (minimum) dates (qryMin2) which are after the ones in qryMin1. This will bring some duplicates with the results of qryMin1; that's ok for now.
SELECT [Multiple Records].[Associate ID], Min([Multiple Records].[Position Effective Date]) AS OtherEarliestDates, [Multiple Records].[Home Department Code]
FROM qryMin1 INNER JOIN [Multiple Records] ON qryMin1.[Associate ID] = [Multiple Records].[Associate ID]
WHERE ((([Multiple Records].[Position Effective Date])>[qryMin1]![EarliestEffectiveDate]) AND (([Multiple Records].[Home Department Code])<>[qryMin1]![Home Department Code]))
GROUP BY [Multiple Records].[Associate ID], [Multiple Records].[Home Department Code];
Now we UNION the results of the two queries (use UNION not UNION ALL as we don't want the duplicates):
SELECT [Associate ID], EarliestEffectiveDate, [Home Department Code] FROM qryMin1
UNION SELECT [Associate ID], OtherEarliestDates, [Home Department Code] FROM qryMin2;
Finally, join this back up to the original table to do whatever you want with the result. Here, I used it to show a flag on the records this mechanism would keep, to see if it's doing the right thing.
SELECT [Multiple Records].[Associate ID], [Multiple Records].[First Name], [Multiple Records].[Last Name], [Multiple Records].[Position Effective Date], [Multiple Records].[Home Department Code], [Multiple Records].[Business Unit Description], IIf([qryMinUnion]![Associate ID] Is Not Null,1,Null) AS [Result?]
FROM [Multiple Records] LEFT JOIN qryMinUnion ON ([Multiple Records].[Home Department Code] = qryMinUnion.[Home Department Code]) AND ([Multiple Records].[Position Effective Date] = qryMinUnion.EarliestEffectiveDate) AND ([Multiple Records].[Associate ID] = qryMinUnion.[Associate ID])
ORDER BY [Multiple Records].[Associate ID], [Multiple Records].[Position Effective Date];
Note: this is a lot of nested queries and horrible summarising. If you're working with big datasets, it will be slow at best, or oversize the database at worst. You might have to split the results into actual tables, rather than nesting subqueries. If it's for feeding an interactive tool, I would find a way to flag the right records as the data gets collected, instead of working it out retrospectively.

Query with checkbox and combobox in Access Database

Good afternoon
This is my query:
SELECT Reference.quote_date AS [Quote Date]
, Reference.agent_ID AS Agent
, Reference.ref_ID AS ReferenceID
, Reference.ref_number AS [Ref Number]
, Customer.title_id AS Title
, Customer.name AS Name
, Customer.surname AS Surname
, Customer.postcode AS Postcode
, Customer.telephone AS Telephone
, Reference.location_ID AS Location
, Reference.policy_ID AS Product
, Reference.price AS Price
, Reference.status_ID AS Status
, Reference.source_ID AS Source
, Reference.calltype_ID AS [Call Type]
, Reference.prize_draw AS [Prize Draw]
, Reference.Call_back_date AS [Call back date]
, Reference.call_back AS [Call back]
, Reference.IsCompleted AS Completed
, Reference.comments AS Comments
FROM Customer INNER JOIN Reference
ON Customer.[customer_ID] = Reference.[customer_ID]
WHERE (((Reference.agent_ID)=[Forms]![Call_Back_Search1]![Combo5])
AND ((Reference.Call_back_date)
Between [Forms]![Call_Back_Search1]![StartDateTxt] And [Forms]![Call_Back_Search1]![EndDatetxt]));
It Currently shows all call backs within certain criteria selected in Call_Back_Search1 form:
- date criteria: between Start and date:End
- and allows to select the Agent (Combobox05).
I wish to add additional criteria to my query :
checkbox called "Completed" to be not ticked
- to show results based only on date range selected (leaving combobox blank)
Wonder if I can ask you for any suggestions
Thank you
I hope someone will find my answer useful
Code is listed below :
SELECT Reference.quote_date AS [Quote Date], Reference.agent_ID AS Agent, Reference.ref_ID AS ReferenceID, Reference.ref_number AS [Ref Number], Customer.title_id AS Title, Customer.name AS Name, Customer.surname AS Surname, Customer.postcode AS Postcode, Customer.telephone AS Telephone, Reference.location_ID AS Location, Reference.policy_ID AS Product, Reference.price AS Price, Reference.status_ID AS Status, Reference.source_ID AS Source, Reference.calltype_ID AS [Call Type], Reference.prize_draw AS [Prize Draw], Reference.Call_back_date AS [Call back date], Reference.call_back AS [Call back], Reference.comments AS Comments, Reference.IsCompleted
FROM Customer INNER JOIN Reference ON Customer.[customer_ID] = Reference.[customer_ID]
WHERE IIF(IsNull(Forms!Call_Back_Search1!Combo5),True,(Reference.agent_ID)=Forms!Call_Back_Search1!Combo5) And ((Reference.Call_back_date) Between Forms!Call_Back_Search1!StartDateTxt And Forms!Call_Back_Search1!EndDatetxt) And (([Reference.IsCompleted])=0);

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];

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.