How to produce quasi duplicates in a Select - sql-server

Im working with MS SQL Server. I cannot explain it really good. I want to change my select statement such that it fills gaps that arent really in the datatable with duplicated values:
Assume following sample data:
col1
col2
col3
423
1
2
423
3
3
I want to fill up the missing col2 numbers which depends on the amount in col3, which would be a result like this:
col1
col2
col3
423
1
2
423
2
2
423
3
3
423
4
3
423
5
3
Its like reverse engineering a select distinct col1,col3
Code:
CREATE TABLE [testtable](
[col1] [smallint] NOT NULL,
[col2] [smallint] NOT NULL,
[col3] [smallint] NULL
)
GO
INSERT INTO testtable
VALUES
(423, 1, 2),
(423, 3, 3)
If its really complicated dont bother solving it, but maybe there is an easy way.

If I understand the question correctly, a recursive CTE is a possible solution:
; WITH rCTE AS (
SELECT 1 AS id, t.col1, t.col2, t.col3
FROM testtable t
UNION ALL
SELECT r.id + 1, r.col1, CONVERT(smallint, r.col2 + 1), r.col3
FROM rCTE r
WHERE r.id + 1 <= r.col3
)
SELECT col1, col2, col3
FROM rCTE

Related

Is there a way in SQL server to apply case statement to multiple columns?

I am looking to apply a CASE condition to multiple columns simultaneously. And, if possible, for multiple tables as well. I know it is possible to replicate the code, but as there are many columns I though there might be a more efficient way.
Example:
SELECT
CASE COLUMN1, COLUMN2, COLUMN3, COLUMN4
WHEN 1 THEN 0
WHEN 2 THEN 1
WHEN 3 THEN 2
WHEN 4 THEN 3
WHEN 5 THEN 4
WHEN 6 THEN 5
WHEN 7 THEN 6
WHEN 8 THEN 7
WHEN 99 THEN NULL
END AS COLUMN1, COLUMN2, COLUMN3, COLUMN4
FROM TABLE1
And if possible, do the same procedure for TABLE2, TABLE3, etc ...
EDIT: The value in the columns are codes representing the number of days the user is online in each application in a platform. So what I'm intending to do is sum those values to get to the total days online. The value 1 represents 0 days online, 2 represents 1 day online and so on. So I need to change those to the actual number of days.
Thank you!
...multiple columns⇛unpivot⇛one column⇛case result⇛pivot⇛multiple columns...
(better to test/compare performance with multiple case-when-end per column)
declare #t table
(
id int identity,
name varchar(1),
col1 int, col2 int, col3 int, col4 int, col5 int, col6 int, col7 int
);
insert into #t(name, col1, col2, col3, col4, col5, col6, col7)
values
('a', 1, 2, 3, 4, 1, 2, 99),
('b', 5, 1, 2, 99, 3, 4, 4),
('c', 4, 3, 99, 4, 99, 2, 99),
('d', 2, 5, 5, 1, 2, 99, 3),
('e', null, null, null, null, null, null, null);
select t.*, '<--before:after-->' as before_after, _case.*
from #t as t
outer apply /* <-- change to cross apply..diff...*/
(
select pvt.*
from
(
--unpivot
select
unp.colname,
--case goes here
case unp.col
when 1 then 10
when 2 then 22
when 3 then 33
when 4 then 40
when 5 then 56
when 99 then NULL
else 0
end as col
from (select t.*) as ut
unpivot (col for colname in (col1, col2, col3, col4, col5, col6, col7) /*<--list of columns...*/ )as unp
) as u
pivot (min(u.col) for u.colname in (col1, col2, col3, col4, col5, col6, col7) /*<--...same list of columns*/ ) as pvt
) as _case;
--

Pivot Table in SQL without using Aggegate Function

I am using SQL server 2012 . I have table like
col1 col2 col3
1 abc AA
2 xyz BB
3 def CC
I want to convert this table into
col1 col2 col3_AA col3_BB col3_CC
1 abc AA
2 xyz BB
3 def CC
please edit table format. I am not able to do
The conditional aggregation might help you
select col1, col2,
max(case when col3 = 'AA' then col3 end) col3_AA,
max(case when col3 = 'BB' then col3 end) col3_BB,
max(case when col3 = 'CC' then col3 end) col3_CC
from table
group by col1, col2
order by col1
Try This
1. Static PIVOT query.
For example, if the column "ITEM_HEAD_ID" values can only be like 1, 2 and 3, then this is what you need. According to your given data, you can use the following query:
SELECT *, (ISNULL([1], 0 ) + ISNULL([2], 0) + ISNULL([3], 0)) AS [Total]
FROM (SELECT [TRXID],
[ITEM_HEAD_ID],
[ITEM_HEAD_AMT]
FROM [Table]) AS t
PIVOT (MAX([ITEM_HEAD_AMT])
FOR [ITEM_HEAD_ID] IN ([1], [2], [3])) AS p;
Note: [Table] is the name of your table.
The result:
TRXID 1 2 3 Total
6 100.00 100.00 300.00 500.00
7 100.00 100.00 300.00 500.00

SQL Table to SQL Table

I have a database table in the following format (populated via .net function, empties are blank, not NULL):
A B C D
Spoons ID
38483
Date Amt Value Type
1/1/2017 2 12 Plastic
1/2/2017 4 30 Silver
1/3/2017 1 9 Wood
How can I write a stored procedure that will result in the following table?
Col1 Col2 Col3 Col4 Col5
----------------------------------------------------
Spoons 38483 1/1/2017 2 Plastic
Spoons 38483 1/2/2017 4 Silver
Spoons 38483 1/3/2017 1 Wood
Note: I am using SQL Server 2016
SELECT LEAD ( [A], 1 ) OVER (ORDER BY [ID] asc) as Col1 FROM Table1 --- (Note I added an ID clmn)
SELECT Top 1 LEAD ( [B], 2 ) OVER (ORDER BY [ID] asc) as Col2 FROM Table1
SELECT ROW_NUMBER() OVER (ORDER BY [ID] asc) AS RowNumber, * FROM Table1 WHERE RowNumber BETWEEN x AND y
Then insert all that into a final table... Simple question = simple answer. I'm just relatively new to sql so it was difficult to figure out on my own.

Select distinct by unique column

For example now I have a table like this:
Col1 Col2 Col3 Col4
1 1 1 1
11 2 3 44
111 2 3 444
1111 3 3 3
I have another table with the same structure, except that it has an unique index include Col2 and Col3. So, I want to select from the first table and insert into the second table, but skip record that have the same unique index. So I can have a new table with data like:
Col1 Col2 Col3 Col4
1 1 1 1
11 2 3 44
1111 3 3 3
How can I do that ?
Currently I'm using Merge Into, but in the situation that my table have millions records it is very slow
Try this query, without unique index/constraint -
Query:
DECLARE #temp TABLE
(
Col1 VARCHAR(10)
, Col2 VARCHAR(10)
, Col3 VARCHAR(10)
, Col4 VARCHAR(10)
)
INSERT INTO #temp (Col1, Col2, Col3, Col4)
VALUES
('1', '1', '1', '1'),
('11', '2', '3', '44'),
('111', '2', '3', '444'),
('1111', '3', '3', '3')
SELECT
Col1 = MIN(Col1)
, Col2
, Col3
, Col4 = MIN(Col4)
FROM #temp
GROUP BY
Col2
, Col3
Output:
Col1 Col2 Col3 Col4
---------- ---------- ---------- ----------
1 1 1 1
11 2 3 44
1111 3 3 3
I doubt you'll be able to do much better than a merge, but you could try optimizing your merge query. Maybe post the query you are currently using? In any case, analytics tend to be fast in these case. Something along the following lines for example:
SELECT Col1, Col2, Col3, Col4
FROM (
SELECT Col1,
Col2,
Col3,
Col4,
MIN(Col1) OVER (PARTITION BY COL2, COL3) AS MinCol1
FROM someTable
) Temp
WHERE Col1 = MinCol1

Update to get check_order

I have a table with values,
col1 col2 col3
1 0 ABA
1 0 ABB
1 0 ABC
2 0 BBA
2 0 BBB
2 0 BBC
I am trying to update the table to see the number of repetition of col1, in this case col1 has repeated 3 times so each update to col2 incremented by 1.
Required output after the update table
col1 col2 col3
1 1 ABA
1 2 ABB
1 3 ABC
2 1 BBA
2 2 BBB
2 3 BBC
A simple row_number() -ing should work
;with TMP as (
select *, row_number() over (partition by col1 order by col3) as RowNum
from tbl
)
update TMP set col2=RowNum
Where
tbl: is your table name
partition by col1: resets the row numbering for each col1 group
order by col3: is the basis for numbering within a col1 group
Assuming you are intending col3 to be in non-descending order, this should do it:
UPDATE MyTable
SET col2=(SELECT COUNT(*)
FROM MyTable AS T2
WHERE T2.col1=T1.col1 AND T2.col3<=T1.col3)
FROM MyTable AS T1
You will get duplicates in col2, if there are duplicates in col3 for a particular col1 value.
In case you are interested, here is a pretty verbose (and more expensive execution wise) solution using a ranking function. It has the same issue (i.e., the count gets repeated) for duplicates in col1/col3, as the previous solution:
UPDATE MyTable
SET col2=(
-- In the following query, DISTINCT merges rank dups caused by col3 dups
-- SELECT TOP(1) MyRank would also work.
SELECT DISTINCT MyRank
FROM (
SELECT col3,
DENSE_RANK() OVER (PARTITION BY col1 ORDER BY col3) AS MyRank
FROM MyTable
WHERE col1=UpdatedTable.col1
) As RankTable
WHERE RankTable.col3=UpdatedTable.col3)
FROM MyTable AS UpdatedTable

Resources