Can someone break down a PIVOT query for me please? - sql

I am looking to pivot this data so the output can count how many people are in each age band...
Below is what I have done, but I don't even think I'm close....
I am using SQL Server 2008
SELECT [OA_Code], Dominant_F_Age, Age_F_90plus, Age_F_85_89, Age_F_80_84, Age_F_75_79, Age_F_70_74, Age_F_65_69, Age_F_60_64,
Age_F_55_59, Age_F_50_54, Age_F_45_49, Age_F_40_44, Age_F_35_39, Age_F_30_34, Age_F_25_29, Age_F_20_24, Age_F_15_19, Age_F_10_14, Age_F_5_9,
Age_F_0_4, Age_2001_F
FROM cen.AgeByGenderOA
PIVOT (
f_Age_data
for [F_Age_Data] in (Age_F_90plus, Age_F_85_89, Age_F_80_84, Age_F_75_79, Age_F_70_74, Age_F_65_69, Age_F_60_64,
Age_F_55_59, Age_F_50_54, Age_F_45_49, Age_F_40_44, Age_F_35_39, Age_F_30_34, Age_F_25_29, Age_F_20_24, Age_F_15_19, Age_F_10_14, Age_F_5_9),
Age_F_0_4)
My table looks like so:
CREATE TABLE AgeByGenderOA(
[OA_Code] AS VARCHAR(50),
[Age_M_0_4] [varchar](50) NULL,
[Age_M_5_9] [varchar](50) NULL,
[Age_M_10_14] [varchar](50) NULL,
[Age_M_15_19] [varchar](50) NULL,
[Age_M_20_24] [varchar](50) NULL,
[Age_M_25_29] [varchar](50) NULL,
[Age_M_30_34] [varchar](50) NULL,
[Age_M_35_39] [varchar](50) NULL,
[Age_M_40_44] [varchar](50) NULL,
[Age_M_45_49] [varchar](50) NULL,
[Age_M_50_54] [varchar](50) NULL,
[Age_M_55_59] [varchar](50) NULL,
[Age_M_60_64] [varchar](50) NULL,
[Age_M_65_69] [varchar](50) NULL,
[Age_M_70_74] [varchar](50) NULL,
[Age_M_75_79] [varchar](50) NULL,
[Age_M_80_84] [varchar](50) NULL,
[Age_M_85_89] [varchar](50) NULL,
[Age_M_90plus] [varchar](50) NULL,
[Dominant_M_Age] [varchar](50) NULL,
[Age_2001_F] [varchar](50) NULL,
[Age_F_0_4] [varchar](50) NULL,
[Age_F_5_9] [varchar](50) NULL,
[Age_F_10_14] [varchar](50) NULL,
[Age_F_15_19] [varchar](50) NULL,
[Age_F_20_24] [varchar](50) NULL,
[Age_F_25_29] [varchar](50) NULL,
[Age_F_30_34] [varchar](50) NULL,
[Age_F_35_39] [varchar](50) NULL,
[Age_F_40_44] [varchar](50) NULL,
[Age_F_45_49] [varchar](50) NULL,
[Age_F_50_54] [varchar](50) NULL,
[Age_F_55_59] [varchar](50) NULL,
[Age_F_60_64] [varchar](50) NULL,
[Age_F_65_69] [varchar](50) NULL,
[Age_F_70_74] [varchar](50) NULL,
[Age_F_75_79] [varchar](50) NULL,
[Age_F_80_84] [varchar](50) NULL,
[Age_F_85_89] [varchar](50) NULL,
[Age_F_90plus] [varchar](50) NULL,
[Dominant_F_Age] [varchar](50) NULL,
[MAPINFO_ID] [varchar](50) NULL)
As you can see it's a huge table. The "Age_M_0_4" columns are populated with numbers.
I would like my output to read
OA_Code, Age, countOfAge
123456, Age_0_4, 26
123456, Age_5_9, 24
789456, Age_0_4, 10
789456, Age_5_9, 12
This would be inclusive of male and female ages.
Anyone fancy taking a crack at this one?
Finally: The data contained in the "Age_M_" Columns is all numbers counts. 50, 40, 2, 0 etc...

You do not want a PIVOT, you need to UNPIVOT the data. Since you are using SQL Server 2008+, you can use CROSS APPLY with a VALUES clause. The code will be similar to this:
select t.OA_Code,
c.age,
sum(cast(c.value as int)) countOfAge
from AgeByGenderOA t
cross apply
(
values
('Age_0_4', Age_M_0_4),
('Age_5_9', Age_M_5_9),
('Age_10_14', Age_M_10_14),
('Age_15_19', Age_M_15_19) ... add the other columns here
) c (age, value)
group by t.OA_Code, c.age
See SQL Fiddle with Demo
Edit, If you want both Male/Female columns you will include ALL of the columns in the values clause, but give them the same age range value:
select t.OA_Code,
c.age,
sum(cast(c.value as int)) countOfAge
from AgeByGenderOA t
cross apply
(
values
('Age_0_4', Age_M_0_4),
('Age_5_9', Age_M_5_9),
('Age_10_14', Age_M_10_14),
('Age_15_19', Age_M_15_19),
('Age_0_4', Age_F_0_4),
('Age_5_9', Age_F_5_9),
('Age_10_14', Age_F_10_14),
('Age_15_19', Age_F_15_19)
) c (age, value)
group by t.OA_Code, c.age;
See SQL Fiddle with Demo

Related

SQL Server 2016 Temporal Tables are Blank

I am trying to create a Temporal Table in SQL Server 2016. The Database is linked to an Azure Data factory which is updated regularly.
I am able to successfully 'create' the Temporal Table, but whenever I try to Select Rows from the table they are blank.
Code for Temporal Table Below:
CREATE TABLE [dbo].[RecoTemp_Test2]
(
[ObservationID] [varchar](100) NULL,
[ObservationTitle] [text] NULL,
[RecoReleaseDate] [date] NULL,
[RecoIsReleased] [varchar](100) NULL,
[ObservationRootCause] [text] NULL,
[EntityID] [varchar](100) NULL,
[AuditID] [varchar](100) NULL,
[RecoID] [varchar](100) NOT NULL,
[ObservationDescription] [text] NULL,
[ObservationBusinessImpactRisk] [text] NULL,
[RecoCode] [varchar](100) NULL,
[RecoTMState] [varchar](100) NULL,
[RecoTMSubState] [varchar](100) NULL,
[RecoPriority] [varchar](100) NULL,
[RecoEffortToComplete] [varchar](100) NULL,
[RecoProgressRate] [varchar](100) NULL,
[RecoLastFollowUpComments] [text] NULL,
[RecoLastFollowUpUserID] [varchar](100) NULL,
[RecoLastFollowUpUserName] [varchar](100) NULL,
[RecoLastFollowUpDate] [date] NULL,
[Reco3Pillars] [varchar](100) NULL,
[RecoTargetDate] [date] NULL,
[RecoTargetDateRevised] [date] NULL,
[RecoLastImplementedDate] [date] NULL,
[RecoLastClosedDate] [date] NULL,
[RecoDescription] [text] NULL,
[RecoManagementActionPlan] [text] NULL,
[RecoExpectedDeliverables] [text] NULL,
[RecoIsPastDue] [varchar](100) NULL,
[RecoIsPastDueEoY] [varchar](100) NULL,
[RecoStatus] [varchar](100) NULL,
[RecoStatusLvl1] [varchar](100) NULL,
[RecoProgressRateLabel] [varchar](100) NULL,
[RecoClosingDeadline] [date] NULL,
[RecoOrigin] [varchar](100) NULL,
[RecoIssuedDate] [date] NULL,
SysStartTime datetime2 GENERATED ALWAYS AS ROW START NOT NULL,
SysEndTime datetime2 GENERATED ALWAYS AS ROW END NOT NULL,
PERIOD FOR SYSTEM_TIME (SysStartTime, SysEndTime),
PRIMARY KEY CLUSTERED ([RecoID] ASC)
)
WITH
(
SYSTEM_VERSIONING = ON (HISTORY_TABLE = [dbo].[RecoTemp_Test2_Hist])
)

SQL Between Function - Wrong Data is reflecting

I am trying to extract the data using between function but wrong data is reflecting
below SQL query i am using,
select * from ORDERSTATUS where ORDERDATE BETWEEN '25-07-2017' AND '31-08-2017';
Also when i run below sql query to extract the data of particular date, i am getting correct output.
select * from ORDERSTATUS where ORDERDATE = '31-08-2017'
Please help me....
and below is the design of my table,
[VENCD] [varchar](50) NOT NULL,
[VENNAME] [varchar](255) NOT NULL,
[ITEMCD] [varchar](50) NOT NULL,
[ITEMNAME] [varchar](255) NOT NULL,
[SKUCD] [varchar](50) NULL,
[SKUNAME] [varchar](255) NULL,
[OORDERNO] [varchar](50) NOT NULL,
[INVNO] [varchar](50) NULL,
[OQTY] [int] NOT NULL,
[COD] [int] NOT NULL,
[SELLINGPRICE] [int] NOT NULL,
[ORDERTYPE] [varchar](50) NOT NULL,
[DSP] [varchar](50) NOT NULL,
[DOCKETNO] [varchar](50) NULL,
[MANIFESTID] [varchar](100) NULL,
**[ORDERDATE] [varchar](50) NOT NULL,**
[CANCELDATE] [varchar](50) NULL,
[SHIPP_INST_DATE] [varchar](50) NULL,
[INVOUTDATE] [varchar](50) NULL,
[PICKUPDATE] [varchar](50) NULL,
[REALDELDATE] [varchar](50) NULL,
[DELCOMPDATE] [varchar](50) NULL,
[RETURNREGDATE] [varchar](50) NULL,
[SHIPP_CANCELDATE] [varchar](50) NULL,
[RTODATE] [varchar](50) NULL,
[DRDATE] [varchar](50) NULL,
[PROSSSTAGE] [varchar](255) NOT NULL,
[REFUND] [varchar](50) NOT NULL,
[CHNLCODE] [varchar](50) NOT NULL,
[CHNLCLASS] [varchar](50) NOT NULL,
[HLCN] [varchar](50) NULL,
[MLCN] [varchar](50) NULL,
[COMMPERC] [int] NULL,
[EXCHCANCELDATE] [varchar](50) NULL,
[RETURNCANCELDATE] [varchar](50) NULL,
[TYPE] [varchar](50) NULL
Can you change where clause with this?
CONVERT (DATETIME, ORDERDATE, 105) BETWEEN '20170725' AND '20170831';
Just use :
WHERE CONVERT(DATE, ORDERDATE) BETWEEN '20170725' AND '20170831'

how to prefix identity column character in msSQL

How can I alter a table's primary identity column to include a letter before the number? I have a table named vendor_master with a primary key VendorID that I would like to store as v1,v2,v3 and so on
CREATE TABLE [dbo].[vendor_master](
[vendorID] [int] IDENTITY(1,1) NOT NULL,
[Vname] [nvarchar](50) NOT NULL,
[Email] [nvarchar](50) NOT NULL,
[Mobile] [bigint] NULL,
[Landline] [bigint] NULL,
[Address] [nvarchar](max) NOT NULL,
[Pincode] [int] NOT NULL)
If it's important to you to have the field in your table, try the following:
CREATE TABLE [dbo].[vendor_master]
(
[vendorID] [int] IDENTITY(1,1) NOT NULL,
[Vname] [nvarchar](50) NOT NULL,
[Email] [nvarchar](50) NOT NULL,
[Mobile] [bigint] NULL,
[Landline] [bigint] NULL,
[Address] [nvarchar](max) NOT NULL,
[Pincode] [int] NOT NULL,
[VendorKey] AS ('v' +CONVERT([varchar](10),[vendorID])) PERSISTED
)
Of course, that will yield you some weird results when sorting, so you might consider padding the data with zeroes to make it a consistent length:
CREATE TABLE [dbo].[vendor_master]
(
[vendorID] [int] IDENTITY(1,1) NOT NULL,
[Vname] [nvarchar](50) NOT NULL,
[Email] [nvarchar](50) NOT NULL,
[Mobile] [bigint] NULL,
[Landline] [bigint] NULL,
[Address] [nvarchar](max) NOT NULL,
[Pincode] [int] NOT NULL,
[VendorKey] AS ('v' +RIGHT('000000000' + CONVERT([varchar](10),[vendorID]),10)) PERSISTED
)
You can't actually do what you are asking. Anyway, there is no reason to add the same letter to the front of a fields value. Instead add the letter in your SELECT statment:
SELECT CONCAT('v', vendorID) AS VendorIDWithPrefix, Vname, Email, Mobile
FROM vendor_master

cannot convert varchar to float in sql

These are my 2 tables
CREATE TABLE [dbo].[dailyRate](
[SYMBOL] [varchar](50) NULL,
[SERIES] [varchar](50) NULL,
[OPENPRICE] [varchar](50) NULL,
[HIGHPRICE] [varchar](50) NULL,
[LOWPRICE] [varchar](50) NULL,
[CLOSEPRICE] [varchar](50) NULL,
[LASTPRICE] [varchar](50) NULL,
[PREVCLOSE] [varchar](50) NULL,
[TOTTRDQTY] [varchar](50) NULL,
[TOTTRDVAL] [varchar](50) NULL,
[TIMESTAMPDAY] [varchar](50) NULL,
[TOTALTRADES] [varchar](50) NULL,
[ISIN] [varchar](50) NULL
)
CREATE TABLE [dbo].[cmpDailyRate](
[ID] [bigint] IDENTITY(1,1) NOT NULL,
[SYMBOL] [varchar](50) NULL,
[SERIES] [varchar](50) NULL,
[OPENPRICE] [decimal](18, 4) NULL,
[HIGHPRICE] [decimal](18, 4) NULL,
[LOWPRICE] [decimal](18, 4) NULL,
[CLOSEPRICE] [decimal](18, 4) NULL,
[LASTPRICE] [decimal](18, 4) NULL,
[PREVCLOSE] [decimal](18, 4) NULL,
[TOTTRDQTY] [bigint] NULL,
[TOTTRDVAL] [decimal](18, 4) NULL,
[TIMESTAMPDAY] [smalldatetime] NULL,
[TOTALTRADES] [bigint] NULL,
[ISIN] [varchar](50) NULL,
[M_Avg] [decimal](18, 4) NULL
)
this is my insert query to fetch data from table to another with casting
Collapse | Copy Code
INSERT into [Stock].[dbo].[cmpDailyRate]
SELECT [SYMBOL],[SERIES],Str([OPENPRICE], 18,4),Str([HIGHPRICE],18,4),
Str([LOWPRICE],18,4),Str([CLOSEPRICE],18,4),Str([LASTPRICE],18,4),Str([PREVCLOSE],18,4),convert(bigint,[TOTTRDQTY]),Str([TOTTRDVAL],18,4),
convert(date, [TIMESTAMPDAY], 105),convert(bigint,[TOTALTRADES]),[ISIN],null
FROM [Stock].[dbo].[DailyRate]
This query runs perfectly in SQL Server 2005, but it's causing errors in SQL Server 2008 (above query run also in SQL Server 2008 when installed; error arise in last few days)
Error :
Error cannot convert varchar to float
What to do?
One of your rows contains invalid data in the columns you are doing the float conversion (Str) on. Use the following strategy to work out which:
SELECT *
FROM [dailyRate]
WHERE IsNumeric([OPENPRICE]) = 0
OR IsNumeric([HIGHPRICE]) = 0
etc etc.
If you do not want to filter out data, a CASE statement might work better for you.
SELECT CASE
WHEN IsNumeric([OPENPRICE]) = 1 THEN [OPENPRICE]
ELSE NULL -- or 0 or whatever
END AS OPENPRICE,
CASE
WHEN IsNumeric([HIGHPRICE]) = 1 THEN [HIGHPRICE]
ELSE NULL -- or 0 or whatever
END AS [HIGHPRICE]
FROM [dailyRate]

SQL Server : rearrange primary key ID to start with 1

CREATE TABLE [dbo].[Customer](
[CusNo] [nvarchar](20) NULL,
[CusName] [nvarchar](100) NULL,
[DateIn] [nvarchar](12) NULL,
[Add1] [nvarchar](255) NULL,
[TelNoH] [nvarchar](50) NULL,
[TelNoHP] [nvarchar](11) NULL,
[DisSR] [nvarchar](50) NULL,
[DisSL] [nvarchar](50) NULL,
[DisCR] [nvarchar](50) NULL,
[DisCL] [nvarchar](50) NULL,
[DisAR] [nvarchar](50) NULL,
[DisAL] [nvarchar](50) NULL,
[ReadSR] [nvarchar](50) NULL,
[ReadSL] [nvarchar](50) NULL,
[ReadCR] [nvarchar](50) NULL,
[ReadCL] [nvarchar](50) NULL,
[ReadAR] [nvarchar](50) NULL,
[ReadAL] [nvarchar](50) NULL,
[PD] [nvarchar](50) NULL,
[R] [nvarchar](50) NULL,
[L] [nvarchar](50) NULL,
[Remarks] [nvarchar](255) NULL,
[ConSR] [nvarchar](50) NULL,
[ConSL] [nvarchar](50) NULL,
[ConCR] [nvarchar](50) NULL,
[ConCL] [nvarchar](50) NULL,
[ConAR] [nvarchar](50) NULL,
[ConAL] [nvarchar](50) NULL,
[Lens] [nvarchar](50) NULL,
[Frame] [nvarchar](50) NULL,
[Amount] [nvarchar](50) NULL,
[LastUserUpdate] [nvarchar](15) NULL,
[LastUpdateDate] [nvarchar](max) NULL
) ON [PRIMARY]
I'm using Microsoft SQL Server 2008, and I have a table Customer in which the CustNo column is the primary key. I have around 30,000 rows with manually entered CustNo.
I want to update all the CustNo to start with 1 and continuously increase by 1 until finish record.
What is the SQL query I have to use?
You can use ROW_NUMBER in a CTE:
WITH CTE AS
(
SELECT CusNo, RN = ROW_NUMBER() OVER (ORDER BY CusNo)
FROM dbo.Customer
)
UPDATE CTE SET CusNo = RN
DEMO with simplified model
But i also strongly recommend to follow #marc_c advice to use the correct datatypes.
yup follow marcs advise. one more thing, ensure your column cusno is an Identity column so that you don't have to go through the entire process of rearranging it again.