SP to populate data as Column store style - sql

I have that stores data in the usual way .
Id | Name | Number
----+------+-------
1 A 101
2 B 102
3 A 103
4 A 105
5 C 104
6 B 106
7 C 108
and so on.
Now I want to convert this table to something similar to column store.
For example all the facility should be ordered and grouped by the name.
Also if a new record arrives with the same the same Name, if should by assigned an ID, which is in the range assigned for that name group.
Just to elaborate. If 'A' has a ID range from 1 to 20 and currently in the table there are 5 ids, so when a new record arrives with Name A, it should be assigned the ID = 6.
Name goes with other names. Every time a ID is populates, the NextID in metatable has to incremented by 1.
As of now I have created a meta table which stores the Min, max ID along with next ID for each name group.
MetaTable
Name MinID MaxId NextID
---------------------------
A 1 30 6
B 31 60 45
C 61 100 78
And using case statements to populate the data in the mail Table. But its very inefficient and the query is long running.
Note: The Number column does not matter.
What could be a more efficient and faster way to achieve this?

SELECT Name,
MIN( ID ),
MAX( ID ),
COUNT(*) OVER ( PARTITION BY Name ) + 1 AS NextID
FROM YourTable
GROUP BY Name;

Related

Merge row values based on other column value

I'm trying to merge the values of two rows based on the value of another row in a different column. Below is my based table
Customer ID
Property ID
Bookings per customer
Cancellations per customer
A
1
0
1
B
2
10
1
C
3
100
1
C
4
100
1
D
5
20
1
Here is the SQL query I used
select customer_id, property_id, bookings_per_customer, cancellations_per_customer
from table
And this is what I want to see. Any ideas the query to get this would be? We use presto SQL
Thanks!
Customer ID
Property ID
Bookings per customer
Cancellations per customer
A
1
0
1
B
2
10
1
C
3 , 4
100
1
D
5
20
1
We can try:
SELECT
customer_id,
ARRAY_JOIN(ARRAY_AGG(property_id), ',') AS properties,
bookings_per_customer,
cancellations_per_customer
FROM yourTable
GROUP BY
customer_id,
bookings_per_customer,
cancellations_per_customer;

Group by in SQL returning error: Selected non-aggregate values must be part of the associated group

I have a table that looks like this:
date store flag
1 5/4/2018 a 1
2 5/4/2018 a 1
3 5/3/2018 b 1
4 5/3/2018 b 0
5 5/2/2018 a 1
6 5/2/2018 b 0
I want to group by date and store and sum the number of flags
i.e. table_a below:
date store total_flag
1 5/4/2018 a 2
3 5/3/2018 b 1
4 5/2/2018 a 1
5 5/2/2018 b 0
This is what I'm trying:
create multiset volatile table flag_summary as (
sel table_a.*, SUM(table_a.flag) as total_flag
group by date, store
)
with data primary index (date, store) on commit preserve rows;
The above gives me an error, "CREATE TABLE Failed. [3504] Selected non-aggregate values must be part of the associated group.
You are selecting all of tableA (including the flag). You should just be pulling the date and the store since you want the sum of the flag.
SELECT date, store, SUM(flag)
FROM tableA
GROUP BY date, store

SQL Server : create batch of Employees and prevent one emp going to multiple batches

My table contains data about Employee. However it is a temporary table and EmployeeID here isn't the primary key. The table may contain a given EmployeeID multiple times.
Now, I have to select batch of records of batchSize, let's consider 200 for now. I'll send these batches to multiple threads.
I have written this query:
WITH SingleBatch AS
(
SELECT
*,
ROW_NUMBER() OVER(ORDER BY EmployeeId) AS RowNumber
FROM
TemperoryTable
)
SELECT *
FROM SingleBatch
WHERE RowNumber BETWEEN 1 AND 200;
the result might be:
EmployeeID EffectiveDate
1 123 01/01/2016
2 541 01/01/2016
------------------------
------------------------
200 978 18/06/2015
for one batch.
This works fine and row numbers change with thread number.
Now suppose, second batch starts with EmployeeId 978. Then this employee will be in first batch as well as second batch. That is, same employee is being sent to multiple threads and may possibly cause conflict.
Although the scenario is very rare, I must avoid this.
What could be the possible solution here?
Sorry I don't get it before, you wish same empolyee can be gotten together? but the total return rows count possible is not fix number. May this is helpful for you.
;WITH t(RowNumber,EmployeeId,other)AS
(
SELECT 1,'a','1' UNION ALL
SELECT 2,'a','12' UNION ALL
SELECT 3,'a','13' UNION ALL
SELECT 4,'b','21' UNION ALL
SELECT 5,'d','41' UNION ALL
SELECT 6,'c','31' UNION ALL
SELECT 7,'c','32'
)
SELECT *,DENSE_RANK()OVER(ORDER BY EmployeeId) AS FilterID,RANK()OVER(ORDER BY EmployeeId) RowsCount FROM t
RowNumber EmployeeId other FilterID RowsCount
----------- ---------- ----- -------------------- --------------------
2 a 12 1 1
3 a 13 1 1
1 a 1 1 1
4 b 21 2 4
6 c 31 3 5
7 c 32 3 5
5 d 41 4 7
Same employeeid has same FilterID, and the RowsCount to control return rows count.
You should get data by RowsCount but rownumber.
For example:
Actual return 6 lines when the RowsCount between 1 and 5.
because the employeeID c have two lines.
Between mean RowNumber>=1 and RowNumber<=200
So next batch should be
RowNumber BETWEEN 201 AND 400
also you can change where clause to
RowNumber>=1 and RowNumber <200 (1-199)
RowNumber>=200 and RowNumber <400 (200-399)

How to get an index of different category returned by "order by" sql in oracle?

We can easily get a sql result as following:
SQL>select Name, Value from table order by Name;
Name Value
------------
A 1
A 2
B 1
C 5
C 6
C 7
However, is there a way to link the name to a number so that an index of different names can be formed? Suppose we don't know how many different names are in the table and don't know what they are.
Name Value idx
-----------------
A 1 0
A 2 0
B 1 1
C 5 2
C 6 2
C 7 2
This can easily be done using a window function:
select Name,
Value,
dense_rank() over (order by name) - 1 as idx
from table
order by Name;

Count sequential field values based on date in seperate table using SQL

I have been trying to devise an SQL query in Access 2010 to count the number of sequential field values which are based over 3 tables using fields with unique ID's
Example
Table1: Course
CorID Date
1 01/01/2012
2 01/03/2012
3 01/02/2012
Table 2: Delegate
DelID StaffID CorID Value CounterField
1 17263 2 99 1
2 17263 1 99 2
3 17263 3 99 3
4 17263 65 4 1
5 17263 44 5 1
6 17263 78 5 2
Table 3: Staff
StaffID Surname
1 Test
2 Smith
17263 Jones
The CounterField increases by 1 where the Value field in Table 2 is the same as the previous Value field. There would be a requirement to ensure that the count only uses the the order based on the course table Date field. The delegate table would also contain more DelID fields than listed and will contain different StaffID values as well.
The CounterField in the above table is an example of what I want the query to be able to do.
Is this possible? Thanks in advance.
If you want to count how many rows you have in Delegate that are not duplicate regarding the Value field:
SELECT count(*)
FROM Delegate
WHERE CounterField = 1
Try running a subquery:
SELECT a.DelID, a.StaffID, a.CorID, a.[Value],
(SELECT Count(*) FROM Delegate b
WHERE b.DelID <= a.DelID AND a.[Value]=b.[Value]) As CounterField
FROM Delegate a;