Related
I try to convert this procedure to PIVOT, but I can't. Does anyone have a solution to help?
I have a table has ItemID, StoreID,Stock
I want to convert it to ItemID, Store1,Store2,Store3...,Stock
sum the stock according to itemID and StoreID then inserts the result as a row.
Many thanks
CREATE table #test222
([Id] int,[ItemID] INT, [storeid] int, [stock] decimal(18,2)
);
INSERT INTO #test222
([Id],[ItemID], [storeid], [stock])
VALUES
(1, 1, 3,10),
(2, 1,1, 20),
(3, 1,1, 30),
(4, 2,1, 40),
(5, 2,2,50),
(6, 2,2,60),
(7, 3,2,70),
(8, 4,2,80),
(9, 4,2,90),
(10, 5,2,100);
select * from #test222;
select ItemID, store1,store2,storeid3,storeid4,storeid5,storeid6,storeid7,storeid8,storeid9,storeid10 stock
from
(
select ItemID, storeid, stock
from #test222
) d
pivot
(
max(stock)
for storeid in (1,2,3,4,5,6,7,8,9,10)
) piv;
Give error:
Msg 102 Level 15 State 1 Line 9
Incorrect syntax near '1'.
Here is a simple PIVOT. Just remember to "feed" your pivot with just only the required columns
Example
Select *
From (
Select ItemID
,Col = 'store'+left(storeid,10)
,val = stock
From #test222
) src
Pivot ( max(val) for Col in ( store1,store2,storeid3,storeid4,storeid5,storeid6,storeid7,storeid8,storeid9,storeid10 ) ) src
Results
I want to fill a temporary table with values from another table and a count value, but it always throws the error:
Column name or number of supplied values does not match table
definition
My code looks like this:
CREATE TABLE #TempTable
([ObjectId] uniqueidentifier, [ListName] nvarchar(255), [HowMany] int)
INSERT INTO #TempTable
SELECT [ObjectId]
,[ListName]
,(SELECT COUNT(*) FROM [ATable] as a WHERE [ObjectId] = a.FK_ObjectId ) AS [HowMany]
FROM [AnotherTable]
It works fine for the other columns but not for the [HowMany] column.
I already tried to cast the SELECT count(*) to an integer but that also did not work.
What am I doing wrong?
I'm checking your request, I think that query below will help you, take a look please, I didn't use a temp table but is just the update the table names to be able to use a temp table.
As you didn't show us the structure of your table, I also made an example to make it simpler to understand, I think :-).
DECLARE #Category as table (
id int,
category nvarchar(50)
);
DECLARE #Product as table (
id int,
idCategory int,
productName nvarchar(50)
);
INSERT INTO #Category
VALUES
(1, 'Category 1'),
(2, 'Category 2'),
(3, 'Category 3')
INSERT INTO #Product
VALUES
(1,1, 'Product 1'),
(2,1, 'Product 2'),
(3,1, 'Product 3'),
(4,2, 'Product 4'),
(5,2, 'Product 5'),
(6,2, 'Product 6'),
(7,2, 'Product 7'),
(8,2, 'Product 8'),
(9,3, 'Product 9'),
(10,3, 'Product 10'),
(11,3, 'Product 11'),
(12,3, 'Product 12')
--To know how many product is used by category
SELECT * FROM
(
SELECT
C.*,
(Count(P.id) over (partition by C.ID order by C.category)) as HowManyProductByCategory
FROM
#Category as C
INNER JOIN #Product as P ON C.id = P.idCategory
) as T
GROUP BY T.id, T.category, T.HowManyProductByCategory
The result
id category HowManyProductByCategory
1 Category 1 3
2 Category 2 5
3 Category 3 4
Best Regards
I have a table with TaxID, Price, DatePurchaced
Every TaxId showning multiple times with different Price and DatePurchaced
I want to Group by TaxId with the Sum(Price) and show the last DatePurchaced
I also want a column with Count(TaxID)
I tryied ome queries but always show me one record the one with the latest datePurchaced
declare #tbl as table (TaxID int, Price money, DatePurchaced datetime)
insert into #tbl (TaxID, Price, DatePurchaced) values (1, 10.5, '2015-03-05 10:25:23');
insert into #tbl (TaxID, Price, DatePurchaced) values (1, 13, '2015-03-09 10:25:23');
insert into #tbl (TaxID, Price, DatePurchaced) values (1, 7, '2015-03-20 10:25:23');
insert into #tbl (TaxID, Price, DatePurchaced) values (2, 10.5, '2015-07-05 10:25:23');
insert into #tbl (TaxID, Price, DatePurchaced) values (2, 8, '2015-07-08 10:25:23');
select t.TaxId as TaxID,
count(t.TaxId) as Cnt,
sum(t.Price) as TotalPrice,
max(t.DatePurchaced) as LastPurchaseDate
from #tbl as t
group by t.TaxId
I have some data as below:
DECLARE #MyTable AS TABLE
(productName varchar(13), test1 int,test2 int)
INSERT INTO #MyTable
(productName, test1,test2)
VALUES
('a', 1,1),
('a', 2,2),
('a', 3,3),
('b', 1,4),
('b', 2,5),
('b', 3,6),
('a', 1,7),
('a', 4,8),
('a', 5,9)
;
SELECT productname,MAX(test1) from #MyTable group BY productname
a MAX query on test1 column gives
a,5
b,3
but I need to have result as
a,3
b,3
a,5
when I have order by test2
You can solve this by using a trick with row_numbers, so that you assign 2 different row numbers, one for the whole data and one that is partitioned by productname. If you compare the difference between these numbers, you can figure out when product name has changed, and use that to determine the max values for each group.
select productname, max(test1) from (
SELECT *,
row_number() over (order by test2 asc) -
row_number() over (partition by productname order by test2 asc) as GRP
from #MyTable
) X
group by productname, GRP
You can test this in SQL Fiddle
If the test2 column is always a row number without gaps, you can use that too instead of the first row number column. If you need ordering in the data, you'll have to for example to use the max of test1 to do that.
Please check the following SQL Select statement
DECLARE #MyTable AS TABLE (productName varchar(13), test1 int,test2 int)
INSERT INTO #MyTable
(productName, test1,test2)
VALUES
('a', 1,1),
('a', 2,2),
('a', 3,3),
('b', 1,4),
('b', 2,5),
('b', 3,6),
('a', 1,7),
('a', 4,8),
('a', 5,9)
DECLARE #MyTableNew AS TABLE (id int identity(1,1), productName varchar(13), test1 int,test2 int)
insert into #MyTableNew select * from #MyTable
--select * from #MyTableNew
;with cte as (
SELECT
id, productName, test1, test2,
case when (lag(productName,1,'') over (order by id)) = productName then 0 else 1 end ischange
from #MyTableNew
), cte2 as (
select t.*,(select sum(ischange) from cte where id <= t.id) grp from cte t
)
select distinct grp, productName, max(test1) over (partition by grp) from cte2
This is implemented according to the following SQL Server Lag() function tutorial
The Lag() function is used to identify and order the groups in table data
Please try this query
DECLARE #MyTable AS TABLE
(productName varchar(13), test1 int,test2 int)
INSERT INTO #MyTable
(productName, test1,test2)
VALUES
('a', 1,1),
('a', 2,2),
('a', 3,3),
('b', 1,4),
('b', 2,5),
('b', 3,6),
('a', 1,7),
('a', 4,8),
('a', 5,9)
;
SELECT productname,MAX(test1)
from #MyTable
where test1 = test2
group BY productname
union all
SELECT productname,MAX(test1)
from #MyTable
where test1 != test2
group BY productname
I have a list of data that looks like this:
Name Date Weight
Person 1 01/01/2014 89KG
Person 2 01/01/2014 62KG
Person 1 07/01/2014 88KG
Person 2 07/01/2014 62KG
Person 1 21/01/2014 85KG
Person 2 21/01/2014 63KG
What I would like to do is select only the records with a distinct name and are the latest dates in a given month. So for this example I would like to only select the person 1 and person 2 records for 21/01/2014 (as this is the latest date). I'm using SQL 2008.
Please see if this works for you.
Sample Data:
IF OBJECT_ID(N'tempdb..#TEMP') > 0
BEGIN
DROP TABLE #TEMP
END
CREATE TABLE #TEMP(Name VARCHAR(20),
WDate VARCHAR(20),
Weight VARCHAR(20))
INSERT INTO #TEMP
VALUES
('Person 1', '01/01/2014', '89KG'),
('Person 2', '01/01/2014', '62KG'),
('Person 1', '07/01/2014', '88KG'),
('Person 1', '07/01/2014', '88KG'),
('Person 2', '07/02/2014', '62KG'),
('Person 1', '21/01/2014', '85KG'),
('Person 2', '21/01/2014', '63KG');
Script:
;WITH cte_DateFormat
AS (
SELECT Name,
CONVERT(DATE, WDate, 103) AS WDate,
Weight
FROM #TEMP
)
, cte_Rank
AS (
SELECT ROW_NUMBER() OVER (PARTITION BY Name,
CAST(YEAR(WDate) AS VARCHAR(4)) + CAST(MONTH(WDate) AS VARCHAR(2)) ORDER BY WDate DESC) AS ID,
Name,
WDate,
Weight
FROM cte_DateFormat
)
SELECT Name,
WDate,
Weight
FROM cte_Rank
WHERE ID = 1
Cleanup Script:
IF OBJECT_ID(N'tempdb..#TEMP') > 0
BEGIN
DROP TABLE #TEMP
END
Please try using DENSE_RANK:
select
*
From (
select
*,
DENSE_RANK() over(PARTITION BY YEAR([Date]),
MONTH([Date])
ORDER BY [Date] desc) Rnk
From tbl
)x where Rnk=1
This will also work, using row partitioning:
SELECT Name, Date, Weight
FROM ( SELECT
Name,
Date,
Weight,
ROW_NUMBER() OVER ( PARTITION BY Name, MONTH(Date)
ORDER BY Date DESC) AS [RowNum]
FROM [YourTableHere]
) Tbl
WHERE Tbl.RowNum = 1
ORDER BY MONTH(Date), Name
Test Script:
DECLARE #Table TABLE (Name VARCHAR(20), Date Date, Weight VARCHAR(20))
INSERT INTO #Table (Name, Date, Weight)
VALUES ('Person 1', '1/1/2014', '89KG'),
('Person 2', '1/1/2014', '62KG'),
('Person 1', '1/7/2014', '88KG'),
('Person 2', '1/7/2014', '62KG'),
('Person 1', '1/21/2014', '85KG'),
('Person 2', '1/21/2014', '63KG'),
('Person 1', '2/1/2014', '84KG'),
('Person 2', '2/1/2014', '61KG'),
('Person 1', '2/11/2014', '83KG'),
('Person 2', '2/11/2014', '60KG')
SELECT Name, Date, Weight
FROM ( SELECT
Name,
Date,
Weight,
ROW_NUMBER() OVER ( PARTITION BY Name, MONTH(Date)
ORDER BY Date DESC) AS [RowNum]
FROM #Table
) Tbl
WHERE Tbl.RowNum = 1
ORDER BY MONTH(Date), Name