order a record by date field's month - sql

Hello I have a table in mssql 2008 that contains a date field.
I'd like to make a select statement which will list all members, sorted by month only.
how do I access only the month part of the date field?
here are some of the member table fields:
id varchar(9) primary key,
f_name varchar(20),
l_name varchar(20),
f_name_english varchar(20),
l_name_english varchar(20),
gender varchar(20),
experience int,
b_date date,
passport varchar(20),

You can also use month() function. (or datepart(month, b_date))
Select id, f_name, l_name....
From YourTableName
Order by month(b_date)

Try this one -
SELECT id
, f_name
, l_name
, f_name_english
, l_name_english
, gender
, experience
, b_date
, passport
FROM YOUR_TABLE
ORDER BY MONTH(b_date)

SELECT * FROM YOURTABLE T
ORDER BY DATEPART(MONTH,T.b_date)
Include DATEPART(YEAR,T.b_date) to ORDER BY if you want to order a result by year too

this will sort by year & month
SELECT
id, f_name, l_name....
FROM
YOUR_TABLE
ORDER BY
CONVERT(Nvarchar(7), b_date, 121)
--or use DatePart(Month, b_date)
-- if you don't care about the year.

Related

Column name or number of supplied values does not match table definition.?

Drop table if exists #populationpercentagevaccine
Create Table #populationpercentagevaccine
(
Continent nvarchar(255),
location nvarchar(255),
Date Datetime,
Population numeric,
New_vaccinations numeric,
cumulative_vaccine numeric
)
My table is executing perfect but that code INSERT INTO giving me problem
Insert into #populationpercentagevaccine
select death.Continent, death.location, death.Date, death.Population, vaccine.New_vaccinations,
sum(convert(int,vaccine.new_vaccinations )) over(partition by death.location order by death.location, death.date) as cumulative_all_vaccine
I created table and inserting into that same table what is causing Column name or number of supplied values does not match table definition that problem
Your table columns and supplied columns in insert was not matching earlier.
Insert into #populationpercentagevaccine
select Continent, [location], [Date], [Population], New_vaccinations
, sum(convert(int,new_vaccinations )) over(partition by [location] order by [location, [date]) as cumulative_all_vaccine
from #populationpercentagevaccine
This was your previous question:
Create Table #populationpercentagevaccine
(
Continent nvarchar(255),
location nvarchar(255),
Date Datetime,
Population numeric,
New_vaccinations numeric,
cumulative_vaccine numeric,
cumulative_all_vaccine numeric
)
Insert into #populationpercentagevaccine
select Continent, [location], [Date], [Population], New_vaccinations, cumulative_vaccine --this was missing earlier
, sum(convert(int,new_vaccinations )) over(partition by [location]
order by [location, [date]) as cumulative_all_vaccine
from #populationpercentagevaccine
your table has 7 columns, your query supplies values only for 6 of them.
either supply the value or insert the identity

Get SQL Distinct Row Without NULL Values

I'm trying to get a distinct row using SQL from set of records that have matching key/id value, but NULLs in different columns. Hard to explain so please see screenshot. Any ideas?
create temporary table my_table (
id varchar(30), segmentdate1 date, converted1 varchar(10), segmentdate2 date, converted2 varchar(10)
);
insert into my_table (
id, segmentdate1, converted1, segmentdate2, converted2
)
values
('Michael','9/15/2020','No',NULL,NULL),
('Michael',NULL,NULL,'7/1/2019','Yes')
;
You seem to want aggregation:
select id, max(segmentdate1) as segmentdate1, max(converted1) as converted1,
max(segmentdate2) as segmentdate2, max(converted2) as converted2
from t
group by id;
Note: I made up names for the columns so they are unique.
This is probably a result set created from another query. That query probably has the wrong group by keys. You should probably fix that query.
declare #my_table table (
id varchar(30), segmentdate1 date, converted1 varchar(10), segmentdate2 date, converted2 varchar(10)
);
insert into #my_table (
id, segmentdate1, converted1, segmentdate2, converted2
)
values
('Michael','9/15/2020','No',NULL,NULL),
('Michael',NULL,NULL,'7/1/2019','Yes')
;
select id,max(isnull(segmentdate1,'1200-01-01')) segmentdate2
,max(isnull(converted1,'')) converted1, max(isnull(segmentdate2,'1200-01-01')) segmentdate2
,max(isnull(converted2,'')) converted2
from #my_table
group by id

Is there any way to speed up this query capturing customer information? Is there a better method for this data?

I have a long query but I'll try to break it down into it's parts.
First, there are the variables,
DECLARE #LocalCompanyCode VARCHAR(5)
SET #LocalCompanyCode = '09'
DECLARE #LocalDivisionCode VARCHAR(5)
SET #LocalDivisionCode = '001'
DECLARE #CustomerBaseFromDate DATETIME --CustomerBase
SET #CustomerBaseFromDate = '1/1/2019'
DECLARE #CustomerBaseToDate DATETIME
SET #CustomerBaseToDate = '5/30/2019'
DECLARE #RecurringBaseFromDate DATETIME --Recurring Base
SET #RecurringBaseFromDate = '1/1/2018'
DECLARE #RecurringBaseToDate DATETIME
SET #RecurringBaseToDate = '1/1/2019'
DECLARE #LifetimeBaseFromDate DATETIME --Lifetime Base
SET #LifetimeBaseFromDate = '1/1/2015'
DECLARE #LifetimeBaseToDate DATETIME
SET #LifetimeBaseToDate = '1/1/2018'
Company Code and Division Code select which Company we are running this query for. Customer Base will be the base of customers that we will be looking at. So in our example, it is the past 5 months.
So for all customers in the past 5 months, we will look in our Recurring Base. This is modular so we can control what time before we consider a customer "lost". We will compare against the recurring base and see how many customers are new customers who only ordered once over the customer and recurring base, and how many customers are recurring customers, those who ordered multiple times over those periods.
Then we will also have our Lifetime base. We will check customers who ordered once or more in our lifetime base, did not order in our recurring base, but did order again in our 5 months customer base. This calculates how many customers are "Reactivated" or were considered lost but bought with us again recently.
Then I declare the four tables
DECLARE #FullBase TABLE
(
Date_Created DATE,
Company_Code VARCHAR(2),
Division_Code VARCHAR(3),
Invoice_Number VARCHAR(50),
CUST_PO VARCHAR(50),
Total_Quantity NUMERIC,
TotalPrice MONEY,
City VARCHAR(50),
State VARCHAR(50),
Zip VARCHAR(50),
CountryCode VARCHAR(50),
Month NUMERIC,
CustomerEmail VARCHAR(MAX),
OrderCountBase NUMERIC,
TotalOrdersBase NUMERIC
)
DECLARE #LifetimeBase TABLE
(
Date_Created DATE,
Company_Code VARCHAR(2),
Division_Code VARCHAR(3),
Invoice_Number VARCHAR(50),
CUST_PO VARCHAR(50),
Total_Quantity NUMERIC,
TotalPrice MONEY,
City VARCHAR(50),
State VARCHAR(50),
Zip VARCHAR(50),
CountryCode VARCHAR(50),
Month NUMERIC,
CustomerEmail VARCHAR(MAX),
OrderCountLifetimeBase NUMERIC,
TotalOrdersLifetimeBase NUMERIC
)
DECLARE #RecurringBase TABLE
(
Date_Created DATE,
Company_Code VARCHAR(2),
Division_Code VARCHAR(3),
Invoice_Number VARCHAR(50),
CUST_PO VARCHAR(50),
Total_Quantity NUMERIC,
TotalPrice MONEY,
City VARCHAR(50),
State VARCHAR(50),
Zip VARCHAR(50),
CountryCode VARCHAR(50),
Month NUMERIC,
CustomerEmail VARCHAR(MAX),
OrderCountRecurringBase NUMERIC,
TotalOrdersRecurringBase NUMERIC
)
DECLARE #CustomerBase TABLE
(
Date_Created DATE,
Company_Code VARCHAR(2),
Division_Code VARCHAR(3),
Invoice_Number VARCHAR(50),
CUST_PO VARCHAR(50),
Total_Quantity NUMERIC,
TotalPrice MONEY,
City VARCHAR(50),
State VARCHAR(50),
Zip VARCHAR(50),
CountryCode VARCHAR(50),
Month NUMERIC,
CustomerEmail VARCHAR(MAX),
OrderCountCustomerBase NUMERIC,
TotalOrdersCustomerBase NUMERIC
)
Then I insert all of our customers into the "FullBase", from the beginning of the Lifetime Base, to the end of the Customer Base
INSERT INTO #FullBase
SELECT Orders.Date_Created
,Orders.Company_Code
,Orders.Division_Code
,Orders.Invoice_Number
,Orders.CUST_PO
,Orders.Total_Quantity
,Orders.Total
,Orders.City
,Orders.State
,Orders.Zip
,Orders.CountryCode
,Orders.Month
,Orders.CustomerEmail
,Row_Number() over (partition by CustomerEmail order by Date_Created asc) OrderCountBase
,Count(*) over (partition by CustomerEmail) TotalOrdersBase
FROM(
Select
CONVERT(Date, OrderCreated) Date_Created
,CONCAT ('0', LEFT(OrderName,1)) Company_Code
,CONCAT ('00', RIGHT(LEFT(OrderName,2),1)) Division_Code
,InvoiceNumber Invoice_Number
,OrderName CUST_PO
,1 Total_Quantity
,TotalPrice Total
,ShippingCity City
,CASE WHEN ShippingCountryCode <> 'US' THEN 'INT' ELSE ShippingProvinceCode END State
,ShippingZip Zip
,ShippingCountryCode CountryCode
,Month( OrderCreated) Month
,Email CustomerEmail
From [SHOPIFY].[shopify_moret].[dbo].orderwrappers O
Where CONVERT(Date, O.OrderCreated) >= Convert(datetime, '05/29/2019')
AND CONCAT ('0', LEFT(O.OrderName,1)) = #LocalCompanyCode--'09'
AND CONCAT ('00', RIGHT(LEFT(O.OrderName,2),1)) = #LocalDivisionCode --'001'
UNION
Select
Archive.Date_Created
,Archive.Company_Code
,Archive.Division_Code
,Archive.Invoice_Number
,('91'+Archive.CUST_PO) CUST_PO
,Archive.Total_Quantity
,Archive.Total
,Archive.City
,Archive.State
,Archive.Zip
,Archive.Country
,Archive.Month
,Archive.CustomerEmail
FROM SpraygroundArchivedOrders Archive
Where Archive.Date_Created < Convert(datetime, '05/29/2019')
) Orders
Where Orders.Date_Created BETWEEN #LifetimeBaseFromDate AND #CustomerBaseToDate
Here is an example of how the data looks like:
https://docs.google.com/spreadsheets/d/1wnjVHcPHHnugywa7Qz-aqctaD4cDI5DxehNna0TyaFU/edit?usp=sharing
Then I use this full base to populate the three other tables with orders from their range.
INSERT INTO #LifetimeBase
SELECT
F.Date_Created
,F.Company_Code
,F.Division_Code
,F.Invoice_Number
,F.CUST_PO
,F.Total_Quantity
,F.TotalPrice
,F.City
,F.State
,F.Zip
,F.CountryCode
,F.Month
,F.CustomerEmail
,Row_Number() over (partition by CustomerEmail order by Date_Created asc) OrderCountLifetimeBase
,Count(*) over (partition by CustomerEmail) TotalOrdersLifetimeBase
FROM #FullBase F
Where F.Date_Created BETWEEN #LifetimeBaseFromDate AND #LifetimeBaseToDate
INSERT INTO #RecurringBase
SELECT
F.Date_Created
,F.Company_Code
,F.Division_Code
,F.Invoice_Number
,F.CUST_PO
,F.Total_Quantity
,F.TotalPrice
,F.City
,F.State
,F.Zip
,F.CountryCode
,F.Month
,F.CustomerEmail
,Row_Number() over (partition by CustomerEmail order by Date_Created asc) OrderCountRecurringBase
,Count(*) over (partition by CustomerEmail) TotalOrdersRecurringBase
FROM #FullBase F
Where F.Date_Created BETWEEN #RecurringBaseFromDate AND #RecurringBaseToDate
INSERT INTO #CustomerBase
SELECT
F.Date_Created
,F.Company_Code
,F.Division_Code
,F.Invoice_Number
,F.CUST_PO
,F.Total_Quantity
,F.TotalPrice
,F.City
,F.State
,F.Zip
,F.CountryCode
,F.Month
,F.CustomerEmail
,Row_Number() over (partition by CustomerEmail order by Date_Created asc) OrderCountCustomerBase
,Count(*) over (partition by CustomerEmail) TotalOrdersCustomerBase
FROM #FullBase F
Where F.Date_Created BETWEEN #CustomerBaseFromDate AND #CustomerBaseToDate
If I just select * from an of the bases, including the full base, the query only takes a few seconds to run and returns 140,000 rows (for the #FullBase) of all customer orders.
However, the final part of this query, which is the part that runs, takes 10 minutes to run for my 6 months of customers
SELECT
CC.CustomerEmail
,CC.TotalOrdersCustomerBase
,RC.TotalOrdersRecurringBase
,LC.TotalOrdersLifetimeBase
From
(
SELECT DISTINCT
C.CustomerEmail
,C.TotalOrdersCustomerBase
FROM
#CustomerBase C
) CC
LEFT JOIN
(
SELECT DISTINCT
R.CustomerEmail
,R.TotalOrdersRecurringBase
FROM
#RecurringBase R
) RC ON CC.CustomerEmail = RC.CustomerEmail
LEFT JOIN
(
SELECT DISTINCT
L.CustomerEmail
,L.TotalOrdersLifetimeBase
FROM
#LifetimeBase L
) LC ON CC.CustomerEmail = LC.CustomerEmail
Does anyone have any tips for me at all? Is there any better way to do this?

How to add temp table to another temp table with extra column

CREATE TABLE #EmpPcodes
(
YearMonth INT,
YEAR INT,
MONTH INT,
RunNo INT,
Amount NUMERIC(18, 3),
GroupCode NvarCHAR(30),
GroupName NvarCHAR(250),
GroupAName NvarCHAR(250),
PayrollGroup INT,
EmployeeId INT
)
CREATE TABLE #pArrangeAllcode
(
YearMonth INT,
YEAR INT,
MONTH INT,
RunNo INT,
Amount NUMERIC(18, 3),
GroupCode NvarCHAR(30),
GroupName NvarCHAR(250),
GroupAName NvarCHAR(250),
PayrollGroup INT,
EmployeeId INT,
CodeArrange INT
)
INSERT INTO #pArrangeAllcode
SELECT YearMonth, YEAR, MONTH, RunNo, Amount, GroupCode, GroupName,
GroupAName, PayrollGroup, EmployeeId,
FROM dbo.#EmpPcodes
SELECT * FROM #pArrangeAllcode
I expect to get the data from the #EmPcodes temp table to #pArrangeAllcode
but it has extra column that I'll use it later ... I always get this error :
Insert Error: Column name or number of supplied values does not match table definition.
Any Help ?
Actually you are missing one column in insert statement whch also need some value:
use this:
INSERT INTO #pArrangeAllcode
SELECT YearMonth, YEAR, MONTH, RunNo, Amount, GroupCode, GroupName,
GroupAName, PayrollGroup, EmployeeId,NULL
FROM dbo.#EmpPcodes
Use below query for inserting records.
INSERT INTO #pArrangeAllcode
SELECT YearMonth, YEAR, MONTH, RunNo, Amount, GroupCode, GroupName,
GroupAName, PayrollGroup, EmployeeId,NULL
FROM dbo.#EmpPcodes
CodeArrange is the extra column exist in the #pArrangeAllcode table. Since it is NOT NULL column, you can skip the particular column name in the insert block and explicitly mention the column name is the INSERT statement.
INSERT INTO #pArrangeAllcode (YearMonth, YEAR, MONTH, RunNo, Amount, GroupCode, GroupName, GroupAName, PayrollGroup, EmployeeId)
SELECT YearMonth, YEAR, MONTH, RunNo, Amount, GroupCode, GroupName, GroupAName, PayrollGroup, EmployeeId
FROM #EmpPcodes
or if you want to store some dummy value in the CodeArrange column then pass NULL
INSERT INTO #pArrangeAllcode (YearMonth, YEAR, MONTH, RunNo, Amount, GroupCode, GroupName, GroupAName, PayrollGroup, EmployeeId, CodeArrange)
SELECT YearMonth, YEAR, MONTH, RunNo, Amount, GroupCode, GroupName, GroupAName, PayrollGroup, EmployeeId, NULL
FROM #EmpPcodes
INSERT INTO #pArrangeAllcode
SELECT dbo.#EmpPcodes.*, NULL
FROM dbo.#EmpPcodes

group by clause

i have a table called table1 and it has following columns.
suppose there are records like localamount is 20,000, 30000,50000, 100000 then as per my condition i have to delete records from this table according to the group by set of site id, till id, transid,shift id where localamount exceeds 10,000... the rest of the records can be available?
my aim is to delete rows from this table where local amount is exceeds 10,0000 according to site id, till id, transid,shift id
SiteId varchar(10),
TillId tinyint,
ShiftId int,
TransId int,
TranDate datetime,
SettlementType varchar(5),
CreditCardNumber varchar(25),
ProductTypeCode varchar(10),
NewProductTypeCode varchar(10),
TransactionType int,
ForeignAmount money,
LocalAmount money,
ProductCode varchar(10)
Im not sure I understand what you are saying, but couldn't you do this without a group by?
delete from table1 where LocalAmount > 10,0000[sic] and SiteId = whatever and TillId = whatever...
obviously take the [sic] out...
Assuming you want to delete the whole group where the sum is > 10000
;with cte as
(
select sum(localamount) over
(partition by siteid, tillid, transid,shiftid) as l,
* from table1
)
delete from cte where l>10000