Fill a table from CSV file with stored procedure - sql-server

I want to import data from this SQL table:
CREATE TABLE [dbo].[TempExchangeRates](
[currency (Libellés)] [nvarchar](255) NULL,
[Currency Code] [nvarchar](255) NULL,
[2019-03] [float] NULL,
[2019-04] [float] NULL,
[2019-05] [float] NULL,
[2019-06] [float] NULL,
[2019-07] [float] NULL,
[2019-08] [float] NULL,
[2019-09] [float] NULL,
[2019-10] [float] NULL,
[2019-11] [float] NULL,
[2019-12] [float] NULL,
[2020-01] [float] NULL,
[2020-02] [float] NULL
)
With sample data:
To this one:
CREATE TABLE [dbo].[ExchangeRates]
(
[IdExchangeRate] [uniqueidentifier] NOT NULL,
[ExchangeRateCode] [nvarchar](10) NULL,
[ExchangeRatePeriodStartDate] [datetime] NULL,
[ExchangeRatePeriodEndDate] [datetime] NULL,
[ExchangeRateValue] [decimal](20, 5) NULL,
[CurrencyCode] [nvarchar](10) NULL,
)
Now I want to call a stored procedure to get fill the real table like that:
I start with stored procedure like that but I'm not sure how I could do that
------------------------- 3. Declare StartDateTable --------------------
DECLARE #StartDateExchangeRate TABLE
(
rowid INT IDENTITY(1,1) NOT NULL,
value float,
startDate date
)
-- Insert Into #StartDateExchangeRate(value, startDate)
--This finds the start dates by finding unmatched values
--SELECT id,value
-- from ExchangeRates
------------------------- 2. Declare EndDateTable --------------------
DECLARE #EndDateExchangeRate TABLE
(
EndDate date
)
Insert Into #ENdDateExchangeRate(EndDate)
--This finds the start dates by finding unmatched values
SELECT EOMONTH(startdate)
FROM #StartDateExchangeRate As ER1
-------------------------3. Join NotYet--------------------------

This question is lacking in details
Assuming the TempExchangeRates columns will vary as time goes on, here is a option that will dynamically UNPIVOT the data so it can be inserted into your final structure.
Example (or dbFiddle)
Select ExchangeRateCode = A.[Currency Code]
,ExchangeRatePeriodStartDate = period
,ExchangeRatePeriodEndDate = EOMonth(period)
,ExchangeRateValue = B.Value
,CurrencyCode = replace(upper(A.[currency (Libellés)]),' ','')
,CreatedBy = 'SomeString'
,CreatededAt = getdate()
From [TempExchangeRates] A
Cross Apply ( Select period = try_convert(date,[Key]+'-01')
,Value = try_convert(float,value)
From OpenJson((Select A.* For JSON Path,Without_Array_Wrapper ))
Where [Key] not in ('currency (Libellés)','Currency Code')
) B
Returns

Related

Finding recurring events that fall between two dates

I have been tasked with creating an events calendar for a website which will be backed by SQL Server. Using some of the information listed at: Calendar Recurring/Repeating Events - Best Storage Method I have created two tables in the database;
CREATE TABLE [Calendar].[Event](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Title] [nvarchar](100) NOT NULL,
[Details] [nvarchar](max) NOT NULL,
[EventType] [int] NOT NULL,
[Dismissable] [bit] NOT NULL DEFAULT ((1)),
[Created] [datetime2](7) NOT NULL DEFAULT (getdate()),
[CreatedBy] [uniqueidentifier] NOT NULL,
[LastEdited] [datetime2](7) NOT NULL DEFAULT (getdate()),
[EditedBy] [uniqueidentifier] NOT NULL
)
CREATE TABLE [Calendar].[EventSchedule](
[Id] [int] IDENTITY(1,1) NOT NULL,
[EventId] [int] NOT NULL,
[StartDate] [datetime2](7) NOT NULL,
[EndDate] [datetime2](7) NULL,
[IntervalDays] [int] NULL,
[IntervalWeeks] [int] NULL,
[IntervalMonths] [int] NULL,
[IntervalYears] [int] NULL,
[WeekDayNumber] [int] NULL,
[MonthWeekNumber] [int] NULL,
[YearMonthNumber] [int] NULL
)
I am now attempting to write a stored procedure to capture all events (singular and recurring) that fall between a date range, but cannot get my head around a catch all solution that doesn't involve generating temporary tables or cursors.
My current roadblock is the events that recur every n days. So far I have the following:
CREATE PROCEDURE Calendar.GetEventsForDateRange
#StartDateRange DATETIME2
#EndDateRange DATETIME2
AS
BEGIN
SELECT * --for brevity
FROM Calendar.EventSchedule
WHERE (StartDate <= #EndDateRange
AND DATEDIFF(DAY, StartDate, #EndDateRange) / IntervalDays >= 1)
OR (StartDate >= #StartDateRange AND StartDate <= #EndDateRange)
END
I have an event where StartDate = 2017-07-02 and IntervalDays = 7. If I pass a #StartDateRange = 2017-07-03 and #EndDateRange = 2017-07-09 the event is correctly returned. If I then change the #StartDateRange = 2017-07-13 and #EndDateRange = 2017-07-15 the event is still returned, where its next occurrence should be 2017-07-16.
How would I alter/amend my current stored procedure to return events that will only occur within a date range?
Any help on this would be greatly appreciated.

Update Item from same table where values are null

I have a table Member where their are duplicate entries and I want to remove one of them, but 1 of the entry has some columns updated and another has some other.
So What I want to do is update but the columns where values exist in 1 and null or empty in another so that both the rows become completely identical and I do not loose any data out of it.
Table Structure:
CREATE TABLE [dbo].[membermobilenumberisnull](
[TransId] [bigint] NOT NULL,
[member_id] [int] NOT NULL,
[gendertype] [int] NULL,
[relationship_rs_code] [nvarchar](2) NULL,
[ration_card_id] [int] NOT NULL,
[uid] [nvarchar](16) NULL,
[member_dob] [datetime] NULL,
[member_name_en] [nvarchar](150) NULL,
[mother_name_en] [nvarchar](150) NULL,
[father_name_en] [nvarchar](150) NULL,
[member_age] [smallint] NULL,
[nationality] [nvarchar](150) NULL,
[MobileNumber] [nvarchar](20) NULL,
[IsUpdated] [bigint] NULL,
[UpdationDate] [datetime] NULL,
[IsDeleted] [bigint] NULL,
[DeletionDate] [datetime] NULL,
[CreationDate] [datetime] NULL,
[UpdatedBy] [nvarchar](250) NULL,
[DeletedBy] [nvarchar](250) NULL,
[MobileNumber1] [nvarchar](20) NULL,
[MobileFlag] [nvarchar](250) NULL
) ON [PRIMARY]
GO
Sample Data
TransId member_dob member_name_en member_age nationality MobileNumber UpdationDate CreationDate
252238402 12-09-1985 PUSHPINDER SINGH 31 IND NULL 30-07-2016
252238403 12-09-1985 PUSHPINDER SINGH 31 IND 8626934377 NULL 30-07-2016
260846102 03-06-1984 VUDDHI DEVI 32 IND 9459209701 19-10-2016 14-08-2016
260846105 03-06-1984 VUDDHI DEVI 32 IND NULL 14-08-2016
Expected Result:
TransId member_dob member_name_en member_age nationality MobileNumber UpdationDate CreationDate
252238402 12-09-1985 PUSHPINDER SINGH 31 IND 8626934377 NULL 30-07-2016
252238403 12-09-1985 PUSHPINDER SINGH 31 IND 8626934377 NULL 30-07-2016
260846102 03-06-1984 VUDDHI DEVI 32 IND 9459209701 19-10-2016 14-08-2016
260846105 03-06-1984 VUDDHI DEVI 32 IND 9459209701 19-10-2016 14-08-2016
Thanks in advance
Example attached:
Assume your combined PK is member_dob,member_name_en,member_age
UPDATE M1
SET M1.MobileNumber = ISNULL(NULLIF(M1.MobileNumber,''),M2.MobileNumber)
,M1.UpdationDate = ISNULL(M1.UpdationDate,M2.UpdationDate)
FROM Member AS M1
INNER JOIN Member AS M2 ON M1.TransId <> M2.TransId
AND M1.member_dob = M2.member_dob
AND M1.member_name_en = M2.member_name_en
AND M1.member_age = M2.member_age
Try this
WITH t2 AS (
SELECT member_dob, member_name_en, member_age, nationality, MobileNumber
FROM <<table>>
WHERE MobileNumber IS NOT NULL
)
UPDATE t1
SET MobileNumber = t2.MobileNumber
FROM <<table>> t1 JOIN t2
ON t1.member_dob = t2.member_dob
AND t1.member_name_en = t2.member_name_en
AND t1.member_age = t2.member_age
AND t2.nationality = t2.nationality
WHERE t1.MobileNumber IS NULL
It seems you want to look at a member_name_en and take a value from whichever of its records, preferring non-null over null. Then simply aggregate and use MIN or MAX to pick such value.
update m
set member_dob = src.max_member_dob
, member_age = src.max_member_age
, nationality = src.max_nationality
etc.
from membermobilenumberisnull m
(
select
member_name_en,
max(member_dob) as max_member_dob,
max(member_age) as max_member_age,
max(nationality) as max_nationality,
etc.
from membermobilenumberisnull
group by member_name_en
) src on src.member_name_en = m.member_name_en;

sql join not showing some records

I'm trying to find all customers who have placed an order but there isn't a callback after their last order date.
My current query:
SELECT dbo.[Order].CustomerId, MAX(OrderDate) AS OrderDate, NextCallbackDate, UserName
FROM dbo.[Order]
LEFT OUTER JOIN (SELECT MAX(CallbackDate) NextCallbackDate, CustomerID
FROM AccountCallbacks
GROUP By CustomerId
) callbacks ON callbacks.CustomerID = dbo.[Order].CustomerID
LEFT OUTER JOIN dbo.aspnet_Users users ON dbo.[Order].UserID = users.UserId
WHERE (PaymentTypeID IN (2, 3, 4, 6, 8))
AND OrderDate >= NextCallbackDate
GROUP BY dbo.[Order].CustomerID, dbo.[Order].OrderDate,callbacks.NextCallbackDate, UserName
ORDER BY dbo.[Order].CustomerID
Tables:
AccountCallBacks:
[CallbackID] [int] IDENTITY(1,1) NOT NULL,
[UserID] [uniqueidentifier] NOT NULL,
[CustomerID] [int] NOT NULL,
[Created] [datetime] NOT NULL,
[CallbackDate] [date] NOT NULL,
[Enabled] [bit] NOT NULL,
[CallbackTimeID] [int] NULL,
[GaryCust] [bit] NULL,
[NotInterestedReasonID] [int] NULL
Order Table:
[OrderID] [int] IDENTITY(1,1) NOT NULL,
[CustomerID] [int] NULL,
[UserID] [uniqueidentifier] NULL,
[OrderDate] [datetime] NOT NULL,
[PaymentTypeID] [int] NULL,
[PaymentStatusID] [int] NOT NULL,
[PaymentDate] [datetime] NULL,
[TransactionRef] [varchar](50) NULL
And the aspnet_Users table is the usual .net membership users table
EDIT:
Apologies! I never actual said what was wrong! My query doesn't give me what I'm expecting one of the rows of data for a particular CustomerID isn't in the result set. And no, there should always be at least one AccountCallbacks.CallbackDate for every CustomerID as I'm joining on the dbo.[Order] table and they wouldn't be in there without first ever being in the AccountCallbacks table.
Feel free to ask any other info, help is greatly appreciated.

The wait operation timed out

I have 2 tables,each contains 4-500k records
CREATE TABLE [dbo].[User][UserId] [int] IDENTITY(1,1) NOT NULL,
[Password] [nvarchar](max) NULL,
[RoleId] [int] NOT NULL,
[Name] [nvarchar](max) NULL,
[Address] [nvarchar](max) NULL,
[Email] [nvarchar](max) NULL,
[Landline] [nvarchar](max) NULL,
[MobileNumberCode] [int] NULL,
[MobileNumber] [nvarchar](max) NULL,
[DateOfBirth] [datetime] NULL,
[MarriageDate] [datetime] NULL,
[CreatedDate] [datetime] NOT NULL,
[UpdatedDate] [datetime] NOT NULL,
[Status] [nvarchar](max) NOT NULL,
[BranchId] [int] NULL,
[UserTitle] [nvarchar](50) NULL,
[MiddleName] [nvarchar](50) NULL,
[LastName] [nvarchar](50) NULL,
[HouseNumber] [nvarchar](50) NULL,
[BuildingNumber] [nvarchar](50) NULL,
[RoadNumber] [nvarchar](50) NULL,
[BlockNumber] [nvarchar](50) NULL,
[City] [nvarchar](50) NULL,
[NearBranchId] [int] NULL,
[MobileIsValid] [bit] NULL,
[EmailIsValid] [bit] NULL,
[Gender] [nvarchar](50) NULL,
[SourceId] [int] NULL)
CREATE TABLE [dbo].[PurchaseOrder]
[PurchaseOrderId] [int] NOT NULL,
[BranchId] [int] NOT NULL,
[PurchaseDate] [datetime] NOT NULL,
[Amount] [decimal](18, 3) NOT NULL,
[UserId] [int] NOT NULL,
[Status] [nvarchar](max) NULL,
[sbs_no] [int] NOT NULL)
And I have stored procedure to get data from these tables using join.
CREATE PROC Sp_SearchCustomer (#FromDate datetime = null,
#ToDate datetime = null,
#RegFromDate datetime = null,
#RegToDate datetime = null)
AS
BEGIN
select a.UserId,a.Name,b.PurchaseOrderId,b.Amount from dbo.[User] a left join PurchaseOrder b on a.UserId=b.UserId
where
((a.CreatedDate >= ''' + cast(#RegFromDate as varchar) + ''')
AND (a.CreatedDate <= ''' + cast(#RegToDate as varchar) + '''))
and ((b.PurchaseDate >= ''' + cast(#FromDate as varchar) + ''')
AND (b.PurchaseDate <= ''' + cast(#ToDate as varchar) + '''))
END
When executing this procedure with date, its getting "The wait operation timed out" exception. Please help to solve this issue.
Your date in your tables and in your Procedure are both saved as varchar. This is perfect and there is no need to convert them to varchar.
Beside, varchar is surrounded by quotes and won't be executed. This is just becoming a string:
where ((a.CreatedDate >= 'cast(#RegFromDate as varchar)')...
There are also way too many useless parenthesis since you are using AND.
Try this instead:
CREATE PROC Sp_SearchCustomer (
#FromDate datetime = null,
#ToDate datetime = null,
#RegFromDate datetime = null,
#RegToDate datetime = null
)
AS
BEGIN
SELECT a.UserId
,a.Name
,b.PurchaseOrderId
,b.Amount
FROM dbo.[User] a
LEFT JOIN PurchaseOrder b
ON a.UserId = b.UserId
WHERE
a.CreatedDate >= #RegFromDate
AND a.CreatedDate <= #RegToDate
AND b.PurchaseDate >= #FromDate
AND b.PurchaseDate <= #ToDate
END
Once the query has been improved, you can test it again.
You should also look at Statistics and Indexes and make sure that Statistics are up-to-date and Indexes are not fragmented.
For Statistics, you can use: exec sp_updatestats
For Indexes on these 2 tables, look at the Fragmentation % and choose to REBUILD or REORGANIZE them.

Get Sum amount against a distinct Value

I want to get sum amount ( Field name Amount) against all the distinct values of Description fields.
CREATE TABLE [dbo].[TransLine](
[TransID] [int] NULL,
[No] [int] NULL,
[Description] [varchar](50) NULL,
[Qty] [varchar](50) NULL,
[Rate] [decimal](18, 2) NULL,
[Amount] [decimal](18, 2) NULL,
[TDate] [datetime] NULL
) ON [PRIMARY]
GO
Kindly reply.
SELECT Description, SUM(Amount) AS [SUM]
FROM dbo.TransLine
GROUP BY Description
You really should at least make an attempt

Resources