How to insert seven kind of ids in a column to all values - sql-server

I have column data. I need to insert ids in another column. Total i have 7 ids. For first 7 values i have to insert these ids and next 7 values, i have to insert same ids and so on.. Can any one please help?
Pay_headID Pay_amount
16414 8000
16415 300
16416 0
16417 200
16418 500
16419 0
16420 0
16414 9000
16415 300
so on ...

you can use CTE and ROW_NUMBER, i have used ordering by Pay_headId:
WITH cte_myTable
AS (SELECT
*,
(ROW_NUMBER() OVER (ORDER BY Pay_headID)) - 1 AS num
FROM myTable)
UPDATE cte_myTable
SET [Pay_headID] =
CASE
WHEN num % 7 = 0 THEN 16414
WHEN num % 7 = 1 THEN 16415
WHEN num % 7 = 2 THEN 16416
WHEN num % 7 = 3 THEN 16417
WHEN num % 7 = 4 THEN 16418
WHEN num % 7 = 5 THEN 16419
WHEN num % 7 = 6 THEN 16420
END
GO
If you want use ordering on how it was inserted, you can set Pay_headIds to null:
update myTable set Pay_headID=null;

You should use RowNum() to give you an artificial incrementing number, divide it by 7 and then Round it.
SELECT FLOOR((ROW_NUMBER() OVER(ORDER BY Pay_HeadID DESC))/7) AS MyID
to get your ids

Related

How can add the cumulative sum from bottom to top?

Create a tmp table and add the num column from top till bottom::
WITH data (num) AS (
VALUES( 1),
( 5),
( 3)
)
SELECT num, sum(num) OVER (ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
FROM data;
All the num added:
num | sum
-----+-----
1 | 1
5 | 6
3 | 9
How can add all the num from bottom till top such as:
num | sum
-----+-----
1 | 9
5 | 8
3 | 3
First of all, there needs to be a second column which provides the ordering you seem to think exists in your table. Note that SQL tables are based on unordered sets of tuples.
WITH data (id, num) AS (
VALUES ROW(1, 1),
ROW(2, 5),
ROW(3, 3)
)
SELECT num, SUM(num) OVER (ORDER BY id DESC) AS sum
FROM data
ORDER BY id;
Here we are taking a rolling sum in the reverse order.
Demo

How to generate random 0 and 1 with 80-20 probability in sql server

I have a Table with 10 records, I have a column (name:RandomNumber) ,that its data type is bit .
now I want to insert data in to this column randomly in such a way that 80 percent of record (8 record) get 0 randomly and 20 percent (2 record) get 1.
For Example Like this:
Id
RandomNumber
1
0
2
0
3
0
4
1
5
0
6
0
7
0
8
1
9
0
10
0
One way is use ORDER BY NEWID() to assign 1 to two rows (20%) and assign 0 to others (remaining 80%) by excluding those assigned 1.
CREATE TABLE dbo.Example(
Id int NOT NULL CONSTRAINT PK_Test PRIMARY KEY
);
INSERT INTO dbo.Example VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
WITH ones AS (
SELECT TOP (2) Id, 1 AS RandomNumber
FROM dbo.Example
ORDER BY NEWID()
)
SELECT Id, 0 AS RandomNumber
FROM dbo.Example
WHERE Id NOT IN(SELECT Id FROM ones)
UNION ALL
SELECT Id, 1 AS RandomNumber
FROM ones
ORDER BY Id;
Alternatively, use ROW_NUMBER() OVER(ORDER BY NEWID()) and a CASE expression:
WITH example AS (
SELECT Id, ROW_NUMBER() OVER(ORDER BY NEWID()) AS rownum
FROM dbo.Example
)
SELECT Id, CASE WHEN rownum <= 2 THEN 1 ELSE 0 END AS RandomNumber
FROM example
ORDER BY Id;

Increasing a Column value by a % range

I have a table in SQL Server 2012. The following query works great:
SELECT TOP 300 [ObjectID], [tbh_Objects].Title, [Discount], [tbh_Section].Title
FROM [ECom].[dbo].[tbh_Objects]
INNER JOIN [tbh_Section] ON tbh_Objects.SectionID = tbh_Section.SectionID
ORDER BY tbh_Objects.AddedDate DESC
I want to fire a query which increases the discount value to a random % in the range of 5-10 for all 300 rows at once. So for eg: If DIscount of ObjectID=500 is 30, and the random value between 5 and 10 is "6", I want it to become 30+6%of30 for ObjectID=500.
Similarly for Object ID=230, let's say discount is 20 and the random value is 8, I want it as 20+8%of20.
The end result of the Discount should always be a whole number and not a decimal, so automatically rounds off.
Is this possible in SQL Server? How?
You need random integers and a Modulus (%) operator. A possible approach to generate a random integers is using a combination of NEWID() and CHECKSUM() functions. The following simplified example is a possible solution to your problem:
SELECT
Discount,
RandomPercent,
CONVERT(int, (Discount * (100.0 + RandomPercent) / 100)) AS NewDiscount
FROM (
SELECT Discount, (ABS(CHECKSUM(NEWID()) % 6) + 5) AS RandomPercent
FROM (VALUES (30), (20), (50), (70), (11), (21), (13), (15), (1), (6)) v (Discount)
) t
Result:
Discount RandomPercent NewDiscount
----------------------------------
30 7 32
20 5 21
50 6 53
70 10 77
11 9 11
21 9 22
13 8 14
15 10 16
1 6 1
6 5 6
If you need an UPDATE statement:
;WITH UpdateCTE AS (
SELECT TOP 300 o.[Discount]
FROM [ECom].[dbo].[tbh_Objects] o
INNER JOIN [tbh_Section] s ON o.SectionID = s.SectionID
ORDER BY o.AddedDate DESC
)
UPDATE UpdateCTE
SET [Discount] = CONVERT(int, (o.[Discount] * (100.0 + (ABS(CHECKSUM(NEWID()) % 6) + 5)) / 100))
If you want to round the new discounts before the integer conversion, use ROUND():
SET [Discount] = CONVERT(
int,
ROUND(o.[Discount] * (100.0 + (ABS(CHECKSUM(NEWID()) % 6) + 5)) / 100, 0)
)

SQL Server Group By Excluding Some Values

I have some records like below:
ID Val Amount
1 0 3
2 0 3
3 0 4
4 1 2
5 1 3
6 2 3
7 2 4
I want to group this data by the column Val and get the sum(amount), but do not group the ones with Val = 0.
The result set I need is like below:
Val Amount
0 3
0 3
0 4
1 5
2 7
I did it by two ways, but none seem to be the best way:
First one is by using unions, like, first having the ones with Val = 0, then grouping the ones with Val <> 0 and unioning the two result sets.
Second one is a little bit better. Let's call the data we have is in the table #Table:
WITH g AS
(
SELECT Val, Amount, CASE WHEN Val = '0' then Val + ID
else Val END A FROM #table
)
SELECT CASE WHEN A LIKE '0%' THEN 0 ELSE A END AS A, SUM(Amount)
FROM g
GROUP BY A
This also works, but being have to concatenate with the ID column (or raw_number) and than using a left function to remove it is not a best practice.
So I'm looking for a better approach, both looking better and performing better as well.
I work on SQL Server 2008, but I'm open to any solutions which require newer versions.
The shortest way of doing it is the following:
SELECT Val, SUM(Amount)
FROM mytable
GROUP BY Val, CASE WHEN Val = 0 THEN ID ELSE 0 END
Demo here
You can also do it using window functions:
;WITH CTE AS (
SELECT ID, Val, Amount,
DENSE_RANK() OVER (PARTITION BY Val
ORDER BY CASE
WHEN Val = 0 THEN ID
ELSE 0
END) AS rank
FROM mytable
)
SELECT Val, SUM(Amount) AS total_amount
FROM CTE
GROUP BY Val, rank
The result set returned by the CTE is:
ID Val Amount rank
--------------------
1 0 3 1
2 0 3 2
3 0 4 3
4 1 2 1
5 1 3 1
6 2 3 1
7 2 4 1
So using rank you can differentiate between 0 and the rest of Val values.
Demo here
You can use both methods and see how they compare to each other in terms of performance.
Use a union here. The top of the below union finds aggregate amounts of values which are not zero, and the bottom brings in the zero value records, not aggregated.
SELECT Val, SUM(Amount) AS Amount
FROM g
WHERE Val <> 0
GROUP BY Val
UNION ALL
SELECT Val, Amount
FROM g
WHERE Val = 0
ORDER BY Val;
Demo

SQL Server Rank Function without taking into account some flagged values

Here is my problem: I have a list of flagged values, I want to see where those values would be in the case they weren't flagged. But I don't want the other flagged values to influence the order.
Note: Flagged values are the ones with CurrentPlace 10000
ID Value CurrentPlace
------------------------
1 2 1
2 8 3
3 3 2
4 4 10000
5 5 10000
6 10 10000
Using:
select *
from
(select
id, value,
rank() over (order by Value asc) as Rank
from
tbl1) r
where
r.ID in (select id from tbl1 where CurrentPlace = 10000)
Desired output:
ID Value Rank
------------------
4 4 3
5 5 3
6 10 4
But I'm getting this instead:
ID Value Rank
------------------
4 4 3
5 5 4
6 10 6
Any help will be appreciated
Thank you guys
I've solved with
SELECT ID, Value, Rank
FROM tbl1 a
CROSS APPLY
(SELECT isnull(max(currentPlace),0) + 1 AS Rank FROM tbl1 WHERE value < a.value and currentPlace <> 10000) b
WHERE a.CurrentPlace = 10000
Please feel free to comment this out.

Resources