Select to PIVOT - sql-server

I have table in SQL as :
DefultDim Name, DisplayValue
-------------------------------------
5637145329, B_MainSector, 4
5637145329, C_SecondSector, 401
5637145329, D_ThirdSection, 40100
5637145329, E_Vendor, 0032
I want to use select to see as :
DefultDim, B_MainSector, C_SecondSector, D_ThirdSection, E_Vendor
--------------------------------------------------------------------
5637145329 4 401 40100 0032
I use this code :
select DEFAULTDIMENSION AS FULLDIM ,[0] AS B_MainSector ,[1] AS C_SecondSector ,[2] AS D_ThirdSection ,[3] AS E_Vendor
from
(select DEFAULTDIMENSION,NAME,RECID,DISPLAYVALUE from DEFAULTDIMENSIONVIEW )
P PIVOT (max(DISPLAYVALUE)
for DISPLAYVALUE in([0],[1],[2],[3])) as PVT
But results seem as :
DefultDim B_MainSector C_SecondSector D_ThirdSection E_Vendor
--------------------------------------------------------------------
5637145329, NULL, NULL, NULL, NULL
5637145329, NULL, NULL, NULL, NULL
5637145329, NULL, NULL, NULL, NULL
5637145329, NULL, NULL, NULL, NULL
Kindly help.

You can try the following Pivot query
create table #Temp (DefultDim Varchar(15), Name Varchar(15), DisplayValue Varchar(5))
Insert Into #Temp Values ('5637145329', 'B_MainSector', '4'),
('5637145329', 'C_SecondSector', '401'),
('5637145329', 'D_ThirdSection', '40100'),
('5637145329', 'E_Vendor', '0032')
select DefultDim, B_MainSector, C_SecondSector, D_ThirdSection, E_Vendor
from
(
select DefultDim, DisplayValue, Name
from #Temp
) d
pivot
(
max(DisplayValue)
for Name in (B_MainSector, C_SecondSector, D_ThirdSection, E_Vendor)
) piv;
You can find the live demo Live Demo Here

I do not have any problems renaming the values
SELECT DefaultDim
,Name
,[4] AS B_itsMe
,[401] AS i_MadeIt
,[32] AS O_K
,[40100] AS Fix_This
FROM(
SELECT * FROM temp.dbo.DefaultDimensionView
PIVOT(
MAX(DisplayValue)
FOR DisplayValue
IN ([4], [401], [32], [40100])
) AS Piv_DisplayValue
) AS R
Sample data

Related

SQL Group By Multiple Columns Having More Than One Unique Value for Grouping Column

I am looking for a way to group by two columns where the first grouping column has more than one unique value for the second grouping column. Below is a sample table with sample data.
CREATE TABLE [dbo].[MyTable](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Type] [varchar](20) NOT NULL,
[UnitOfMeasure] [varchar](20) NULL,
CONSTRAINT [PK_MyTable] PRIMARY KEY CLUSTERED
(
[ID] ASC
) ON [PRimary]
) ON [PRimary];
INSERT INTO [MyTable] (Type, UnitOfMeasure)
VALUES ('height', 'cm')
, ('distance', 'km')
, ('weight', 'kg')
, ('Glucose', 'mg/dL')
, ('weight', 'kg')
, ('Duration', 'hours')
, ('Glucose', 'mg/dL')
, ('Glucose', 'mg/dL')
, ('height', 'cm')
, ('Allergy', 'kUnits/L')
, ('Volume', 'mL')
, ('height', 'inch')
, ('height', 'cm')
, ('Chloride', 'mmol/L')
, ('Volume', 'cup')
, ('distance', 'km')
, ('Volume', 'cup')
, ('Duration', 'hours')
, ('Chloride', 'mmol/L')
, ('Duration', 'minutes');
The desired out put is as follows.
Type UnitOfMeasure
Duration hours
Duration minutes
height cm
height inch
Volume cup
Volume mL
This output includes Duration because it has two unit of measures. However, it does not include weight, nor Chloride, due to it having only a single unit of measure.
You can use a CTE to get a DISTINCT COUNT, and then use an EXISTS with a further DISTINCT. I expect this to be a little expensive though, and ideally you probably want to address those duplicate rows you have.
WITH Counts AS(
SELECT [Type],
COUNT(DISTINCT UnitOfMeasure) AS DistinctMeasures
FROM dbo.MyTable
GROUP BY [Type])
SELECT DISTINCT
[Type],
UnitOfMeasure
FROM dbo.MyTable MT
WHERE EXISTS (SELECT 1
FROM Counts C
WHERE C.[Type] = MT.[Type]
AND C.DistinctMeasures > 1);
You can do it with EXISTS:
SELECT DISTINCT t.[Type], t.[UnitOfMeasure]
FROM [MyTable] t
WHERE EXISTS (
SELECT 1 FROM [MyTable]
WHERE [Type] = t.[Type] AND [UnitOfMeasure] <> t.[UnitOfMeasure]
)
See the demo.
Results:
> Type | UnitOfMeasure
> :------- | :------------
> Duration | hours
> Duration | minutes
> height | cm
> height | inch
> Volume | cup
> Volume | mL
You can do this with window functions only. Just compare the min and max unit per type: if they differ, then you know you have at least two distinct values, and you can retain the corresponding rows:
select distinct type, unitofmeasure
from (
select t.*,
min(unitofmeasure) over(partition by type) min_unit,
max(unitofmeasure) over(partition by type) max_unit
from mytable t
) t
where min_unit <> max_unit

How to fetch self referenced column value in sql

I have two tables with column
CREATE TABLE Dept(
[ID] [int] IDENTITY(1,1) NOT NULL,
[Next_ID] [int] NULL,
[Name] [varchar](50) NOT NULL,
[Bundle_ID] [int] NULL
)
And
CREATE TABLE Bundle(
[Bundle_ID] [int] NOT NULL,
[Bundle_Name] [varchar](40) NOT NULL
)
I would like to fetch nextID name so i tried
SELECT dept.ID, dept.Next_ID, currentbundle.Bundle_Name CurrentBundleName
FROM Dept dept
join Bundle currentbundle on currentbundle.Bundle_ID = dept.Bundle_ID
join dept dept1 on dept1.Next_ID=dept.ID
With this, I get only currentBundleName. How to fetch nextbundlename?
I would like to have output like this
ID NextID CurrentBundleName NextBundleName
********************************************************
1 3 template excel
3 4 excel word
4 NULL word NULL
CREATE TABLE #Dept(
[ID] [int] IDENTITY(1,1) NOT NULL,
[Next_ID] [int] NULL,
[Name] [varchar](50) NOT NULL,
[Bundle_ID] [int] NULL
)
CREATE TABLE #Bundle(
[Bundle_ID] [int] NOT NULL,
[Bundle_Name] [varchar](40) NOT NULL
)
INSERT INTO #Bundle
( Bundle_ID, Bundle_Name )
VALUES
( 1, 'One' ),
( 2, 'Two' ),
( 3, 'Three' ),
( 4, 'Four' )
INSERT INTO #Dept
( Next_ID, Name, Bundle_ID )
VALUES
( NULL, 'First', 1),
( 1, 'Second', 2),
( 2, 'Third', 3),
( 3, 'Fouth', 4)
select
d.ID,
d.Name AS DeptName,
d2.ID AS NextDeptId,
d2.Name AS NextDeptName,
b.Bundle_Name AS BundleName,
b2.Bundle_Name AS NextBundleName
FROM #Dept d
JOIN #Bundle b ON b.Bundle_ID = d.Bundle_ID
LEFT JOIN #Dept d2 ON d2.id=d.Next_ID
LEFT JOIN #Bundle b2 ON b2.Bundle_ID = d2.Bundle_ID
DROP TABLE #Bundle
DROP TABLE #Dept
Corrected Results:
ID DeptName NextDeptId NextDeptName BundleName NextBundleName
1 First NULL NULL One NULL
2 Second 1 First Two One
3 Third 2 Second Three Two
4 Fouth 3 Third Four Three
Please try this :
SELECT d.id,
d.next_id,
b.Bundle_Name current_bundle_name,
b1.Bundle_Name AS next_bundle_name
FROM dept d
INNER JOIN bundle b ON b.Bundle_ID = d.Bundle_ID
LEFT JOIN bundle b1 ON b1.Bundle_ID = d.Next_ID

SQL Query for Outer Join with Group By

I have the Months Table with MonthName, MonthNumber and Fiscal Year starts with July so I have assigned the values to the months like
MonthName=July and MonthNumber=1
MonthName=August and MonthNumber=2.
I have another Domain table BudgetCategory and it has BudgetCategoryId, BudgetCategoryName.
The PurchaseOrder table has OrderID, PurchaseMonth, BudgetCategoryId.
Now I want the query to find out the Monthly Purchases SUM(TotalCost) for every BudgetCategory. If there are no purchases for any BudgetCategoryId I want to display the zero in report.
Schema of Table:
CREATE TABLE [dbo].[BudgetCategory](
[BudgetCategoryId] [numeric](18, 0) NOT NULL,
[BudgetCategoryName] [varchar](50) NULL,
[TotalBudget] [nvarchar](50) NULL)
CREATE TABLE [dbo].[PurchaseOrder](
[OrderId] [bigint] NOT NULL,
[BudgetCategoryId] [bigint] NULL,
[PurchaseMonth] [nvarchar](50) NULL,
[QTY] [bigint] NULL,
[CostPerItem] [decimal](10, 2) NULL,
[TotalCost] [decimal](10, 2) NULL)
CREATE TABLE [dbo].[MonthTable](
[MonthNumber] [bigint] NULL,
[MonthName] [nvarchar](30) NULL)
Try this:
select a.BudgetCategoryName,
ISNULL(c.MonthName,'No purchase') as Month,
sum(ISNULL(TotalCost,0)) as TotalCost
from #BudgetCategory a left join #PurchaseOrder b on a.BudgetCategoryId = b.BudgetCategoryId
left join #MonthTable c on b.PurchaseMonth = c.[MonthName]
group by a.BudgetCategoryName,c.MonthName
order by a.BudgetCategoryName
Tested with this data
INSERT #BudgetCategory
VALUES (1,'CategoryA',1000),
(2,'CategoryB',2000),
(3,'CategoryC',1500),
(4,'CategoryD',2000)
INSERT #PurchaseOrder (OrderId,BudgetCategoryId,TotalCost,PurchaseMonth)
VALUES (1,1,550,'July'),
(2,1,700,'July'),
(3,2,600,'August')
INSERT #MonthTable
VALUES
(1,'July'),
(2,'August')
It will produce this results:
Let me know if this could help you
SELECT b.*, m.MonthNumber, q.[BudgetCategoryId], q.[PurchaseMonth], ISNULL(q.[TotalCost],0)
FROM [dbo].[BudgetCategory] b
LEFT JOIN
(
SELECT [BudgetCategoryId], [PurchaseMonth], sum([TotalCost]) [TotalCost]
FROM [dbo].[PurchaseOrder] p
GROUP BY p.[BudgetCategoryId], [PurchaseMonth]
) q ON b.BudgetCategoryId = q.BudgetCategoryId
LEFT JOIN [dbo].[MonthTable] m ON q.[PurchaseMonth] = m.[MonthName]

Select only one (NOT TOP) record base upon desired data priority

I have a sub-query that is part of a large query but really I think this problem is isolated to the subquery. If I am wrong however I will gladly post the entire thing.
I have records where a person may have 4 or 5 or 8 or 0 etc. entries. We want only one record but we have a preference. We'll take record B if record A isn't there etc.
Originally I was joining to the table
.....snip.....
LEFT JOIN [COMMUNICATION] Comm ON Peeps.PEOPLE_ID = Comm.PEOPLE_ID
and getting results such as
ID FIRST LAST ADDY BIZ CELL FAX HOME
21930 Person Name Addy 3237532500 NULL NULL NULL
21930 Person Name Addy NULL 3237910815 NULL NULL
21930 Person Name Addy NULL NULL 3235869055 NULL
21930 Person Name Addy NULL NULL NULL 3238660704
21930 Person Name Addy NULL NULL NULL NULL
In the communications table I really have 5 records so it is not a join issue.
Now I want only one row in this preference....
Home
Cell
Biz
Fax
So my first attempt was to do a subquery with TOP(1) but of course that only returns the top row of the table. I read on cte and am familiar with them but in this case I need to be able to join and not sure how you would 1. get the cte to order the records in the desired business priority and 2. how to join to it.
If you could just point my nose in the right direction or tell me what to study I will gladly do my own work.
Thanks
Without further information, this is what I came up to:
create table #temp_table (
[id] int,
[first] varchar(50),
[last] varchar(50),
[addy] varchar(50),
[biz] varchar(50) null,
[cell] varchar(50) null,
[fax] varchar(50) null,
[home] varchar(50) null
)
insert into #temp_table
select 21930, 'Person', 'Name', 'Addy', '3237532500', null, null, null union all
select 21930, 'Person', 'Name', 'Addy', null, '3237910815', null, null union all
select 21930, 'Person', 'Name', 'Addy', null, null, '3235869055', null union all
select 21930, 'Person', 'Name', 'Addy', null, null, null, '3238660704' union all
select 21930, 'Person', 'Name', 'Addy', null, null, null, null
;with ordered as(
select
*,
rn = row_number() over( partition by id
order by
case
when home is not null then 1
when cell is not null then 2
when biz is not null then 3
when fax is not null then 4
else 9999
end
)
from #temp_table
)
select
[id],
[first],
[last],
[addy],
[biz],
[cell],
[fax],
[home]
from ordered
where
rn = 1
drop table #temp_table

Copy Distinct Records Based on 3 Cols

I have loads of data in a table called Temp. This data consists of duplicates.
Not Entire rows but the same data in 3 columns. They are HouseNo,DateofYear,TimeOfDay.
I want to copy only the distinct rows from "Temp" into another table, "ThermData."
Basically what i want to do is copy all the distinct rows from Temp to ThermData where distinct(HouseNo,DateofYear,TimeOfDay). Something like that.
I know we can't do that. An alternative to how i can do that.
Do help me out. I have tried lots of things but haven't solved got it.
Sample Data. Values which are repeated are like....
I want to delete the duplicate row based on the values of HouseNo,DateofYear,TimeOfDay
HouseNo DateofYear TimeOfDay Count
102 10/1/2009 0:00:02 AM 2
102 10/1/2009 1:00:02 AM 2
102 10/1/2009 10:00:02 AM 2
Here is a Northwind example based on the Orders table.
There are duplicates based on the (EmployeeID , ShipCity , ShipCountry) columns.
If you only execute the code between these 2 lines:
/* Run everything below this line to show crux of the fix */
/* Run everything above this line to show crux of the fix */
you'll see how it works. Basically:
(1) You run a GROUP BY on the 3 columns of interest. (derived1Duplicates)
(2) Then you join back to the table using these 3 columns. (on ords.EmployeeID = derived1Duplicates.EmployeeID and ords.ShipCity = derived1Duplicates.ShipCity and ords.ShipCountry = derived1Duplicates.ShipCountry)
(3) Then for each group, you tag them with Cardinal numbers (1,2,3,4,etc) (using ROW_NUMBER())
(4) Then you keep the row in each group that has the cardinal number of "1". (where derived2DuplicatedEliminated.RowIDByGroupBy = 1)
Use Northwind
GO
declare #DestinationVariableTable table (
NotNeededButForFunRowIDByGroupBy int not null ,
NotNeededButForFunDuplicateCount int not null ,
[OrderID] [int] NOT NULL,
[CustomerID] [nchar](5) NULL,
[EmployeeID] [int] NULL,
[OrderDate] [datetime] NULL,
[RequiredDate] [datetime] NULL,
[ShippedDate] [datetime] NULL,
[ShipVia] [int] NULL,
[Freight] [money] NULL,
[ShipName] [nvarchar](40) NULL,
[ShipAddress] [nvarchar](60) NULL,
[ShipCity] [nvarchar](15) NULL,
[ShipRegion] [nvarchar](15) NULL,
[ShipPostalCode] [nvarchar](10) NULL,
[ShipCountry] [nvarchar](15) NULL
)
INSERT INTO #DestinationVariableTable (NotNeededButForFunRowIDByGroupBy , NotNeededButForFunDuplicateCount , OrderID,CustomerID,EmployeeID,OrderDate,RequiredDate,ShippedDate,ShipVia,Freight,ShipName,ShipAddress,ShipCity,ShipRegion,ShipPostalCode,ShipCountry )
Select RowIDByGroupBy , MyDuplicateCount , OrderID,CustomerID,EmployeeID,OrderDate,RequiredDate,ShippedDate,ShipVia,Freight,ShipName,ShipAddress,ShipCity,ShipRegion,ShipPostalCode,ShipCountry
From
(
/* Run everything below this line to show crux of the fix */
Select
RowIDByGroupBy = ROW_NUMBER() OVER(PARTITION BY ords.EmployeeID , ords.ShipCity , ords.ShipCountry ORDER BY ords.OrderID )
, derived1Duplicates.MyDuplicateCount
, ords.*
from
[dbo].[Orders] ords
join
(
select EmployeeID , ShipCity , ShipCountry , COUNT(*) as MyDuplicateCount from [dbo].[Orders] GROUP BY EmployeeID , ShipCity , ShipCountry /*HAVING COUNT(*) > 1*/
) as derived1Duplicates
on ords.EmployeeID = derived1Duplicates.EmployeeID and ords.ShipCity = derived1Duplicates.ShipCity and ords.ShipCountry = derived1Duplicates.ShipCountry
/* Run everything above this line to show crux of the fix */
)
as derived2DuplicatedEliminated
where derived2DuplicatedEliminated.RowIDByGroupBy = 1
select * from #DestinationVariableTable
emphasized text*emphasized text*emphasized text

Resources