joining table in h2 database but not able to select data - sql-server

there is two table:- 1. product 2. batch
-:product table:-
code
---------
001
002
-:Batch table:-
batchno productcode Qty
--------- ----------- -----
B0002 001 5
B0003 001 10
B0004 001 15
C0005 002 20
C0034 002 10
where batch.qty integer,product.code varchar(20),batch.product varchar(20).
This code is working in sql server 2008 but not in h2 embeded database.
every fields and its data types are same as in sql server 2008.
i want output like :-
productcode qty
----------- ----
001 30
002 30
please help .
thanks in advance.
i am using this query:- SELECT product.code,(SELECT sum(batch.qty) FROM batch WHERE batch.productcode = product.code)FROM product;

According to your tables and your required result run the following sql command:
SELECT batch.productcode, SUM(batch.qty) FROM batch GROUP BY batch.productcode;

Related

Fill remaining dates between dates in SQL Server

I have the following data in a table:
ItemID
Date
Status
001
2021-01-12
Active
001
2021-01-16
Discontinued
001
2021-01-20
Active
I need to fill in the remaining dates like this:
ItemID
Date
Status
001
2021-01-12
Active
001
2021-01-13
Active
001
2021-01-14
Active
001
2021-01-15
Active
001
2021-01-16
Discontinued
001
2021-01-17
Discontinued
001
2021-01-18
Discontinued
001
2021-01-19
Discontinued
001
2021-01-20
Active
Also, I need suggestions on will it be efficient to fill data like this or create two different columns for Valid from and to dates in Data Warehouse?
I have a working solution, but I am sure there are better ways to do this. I assume you would like a working solution, and then you can investigate the performance and optimize it if need be.
As pointed out in the comments, to solve this it is easiest if you have a calendar table. I assume you do not have anything, so I start from scratch. I generate the numbers 0 - 9 and then through successive CROSS JOINS I use those numbers to generate the numbers 0 - 10,000. I did make the assumption that there are not more than 10,000 days between the minimum date and the maximum date, but if this is not correct you can change the code to generate more numbers.
My approach uses several common table expressions as this is how I work to incrementally solve a problem. So first generate the digits, then generate numbers, then determine the minimum and maximum dates for each ItemID, then create a recordset that includes all the dates between the minimum and maximum dates for each ItemID, then I LEFT JOIN this to copy the Status. Finally, you have the interesting problem of how to get the last non NULL value for a column, and there are several approaches. Here is one article of many you can see different approaches: https://www.mssqltips.com/sqlservertip/7379/last-non-null-value-set-of-sql-server-records/ I used the approach that uses the MAX function in a window.
So, putting this all together into a script and starting with your data in a table variable (as well as adding some records for another test), the whole things looks like this:
DECLARE #Data TABLE([ItemID] VARCHAR(3), [Date] DATE, [Status] VARCHAR(15));
INSERT INTO #Data ([ItemID],[Date],[Status])
VALUES ('001', '2021-01-12', 'Active'), ('001', '2021-01-16','Discontinued'),('001', '2021-01-20','Active'),
('002','2022-02-01','Active'), ('002','2022-03-01','Discontinued');
;WITH digits (I) AS
(
SELECT I
FROM (VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) AS digits (I)
)
,integers (I) AS (
SELECT D1.I + (10*D2.I) + (100*D3.I) + (1000*D4.I)
FROM digits AS D1 CROSS JOIN digits AS D2 CROSS JOIN digits AS D3 CROSS JOIN digits AS D4
), itemMinMaxDates AS (
SELECT [ItemID], MIN([Date]) AS [MinDate], MAX([Date]) AS [MaxDate]
FROM #Data GROUP BY [ItemID]
), itemsWithAllDates AS
(
SELECT [imm].[ItemID], DATEADD(DAY,i.I, imm.[MinDate]) AS [Date] FROM [itemMinMaxDates] AS imm CROSS JOIN [integers] AS i
WHERE DATEADD(DAY,i.I, imm.[MinDate]) BETWEEN imm.[MinDate] AND imm.[MaxDate]
), itemsWithAllDatesAndStatus AS
(
SELECT [allDates].[ItemID], [allDates].[Date], [d].[Status] FROM [itemsWithAllDates] AS allDates
LEFT OUTER JOIN #Data AS d ON [allDates].[ItemID] = [d].[ItemID] AND [allDates].[Date] = d.[Date]
), grp AS
(
SELECT [itemsWithAllDatesAndStatus].[ItemID],
[itemsWithAllDatesAndStatus].[Date],
[itemsWithAllDatesAndStatus].[Status],
MAX(IIF([itemsWithAllDatesAndStatus].[Status] IS NOT NULL, [itemsWithAllDatesAndStatus].[Date], NULL)) OVER (PARTITION BY [itemsWithAllDatesAndStatus].[ItemID] ORDER BY [itemsWithAllDatesAndStatus].[Date] ROWS UNBOUNDED PRECEDING) AS grp
FROM itemsWithAllDatesAndStatus
)
SELECT [grp].[ItemID], [grp].[Date],
MAX([grp].[Status]) OVER (PARTITION BY [grp].[ItemID], grp ORDER BY [grp].[Date] ROWS UNBOUNDED PRECEDING) AS [Status]
FROM [grp]
ORDER BY [grp].[ItemID], [grp].[Date];
The result is what you have shown (as well as the data I included for a test):
ItemID
Date
Status
001
2021-01-12
Active
001
2021-01-13
Active
001
2021-01-14
Active
001
2021-01-15
Active
001
2021-01-16
Discontinued
001
2021-01-17
Discontinued
001
2021-01-18
Discontinued
001
2021-01-19
Discontinued
001
2021-01-20
Active
002
2022-02-01
Active
002
2022-02-02
Active
002
2022-02-03
Active
002
2022-02-04
Active
002
2022-02-05
Active
002
2022-02-06
Active
002
2022-02-07
Active
002
2022-02-08
Active
002
2022-02-09
Active
002
2022-02-10
Active
002
2022-02-11
Active
002
2022-02-12
Active
002
2022-02-13
Active
002
2022-02-14
Active
002
2022-02-15
Active
002
2022-02-16
Active
002
2022-02-17
Active
002
2022-02-18
Active
002
2022-02-19
Active
002
2022-02-20
Active
002
2022-02-21
Active
002
2022-02-22
Active
002
2022-02-23
Active
002
2022-02-24
Active
002
2022-02-25
Active
002
2022-02-26
Active
002
2022-02-27
Active
002
2022-02-28
Active
002
2022-03-01
Discontinued
Like I said, this is a working solution, but it is likely not the best or most efficient solution - but it gets you up and running.

SQL delete rows based on date difference

The situation is quite complicated to express in the title. An example should be much easier to understand.
My table A:
uid id ticket created_date
001 1 movie 2015-01-23 08:23:16
002 25 TV 2012-01-13 12:02:20
003 1 movie 2015-02-01 07:15:36
004 1 movie 2014-02-15 15:38:40
What I need to achieve is to remove duplicate records that appear within 31 days between each other and retain the record that appear first. So the above table would be reduced to B:
uid id ticket created_date
001 1 movie 2015-01-23 08:23:16
002 25 TV 2012-01-13 12:02:20
004 1 movie 2014-02-15 15:38:40
because the 3rd row in A were within 31 days of row 1 and it appeared later than row 1 (2015-02-01 vs 2015-01-23), so it gets removed.
Is there a clean way to do this?
I would suggest the following approach:
SELECT A.uid AS uid
INTO #tempA
FROM A
LEFT JOIN A AS B
ON A.id=B.id AND A.ticket=B.ticket
WHERE DATEDIFF(SECOND,B.date,A.date) > 0 AND
DATEDIFF(SECOND,B.date,A.date) < 31*24*60*60;
DELETE FROM A WHERE uid IN (SELECT uid FROM #tempA);
This is assuming that by 'duplicate records' you mean records that have both identical id as well as identical ticket fields. If that's not the case you should adjust the ON clause accordingly.

SQL Server 2008 Perform a draw between 2 tables

I have 2 tables on SQL Server 2008, each one has a single column and the same rows count number:
USERS OPERATION
Name Operation
----------- -----------
John W383
William R823
Karen X933
Peter M954
Alex S744
I need to perform every week a random draw between the 2 tables to get something like the follow and save it into a 3rd. table:
DRAW_RESULT:
Name Operation_Assigned Week_Number
----------------------------------------------
Peter M954 2
William W383 2
John S744 2
Alex X933 2
Karen R823 2
Name Operation_Assigned Week_Number
----------------------------------------------
William R823 3
Alex M954 3
Karen X933 3
John S744 3
Peter W383 3
How can I do this using T-SQL?
If I understood correctly what you're doing, something like this should work:
select name, operation from (
select
row_number() over (order by (select null)) as RN,
name
from
users
) U join (
select
row_number() over (order by newid()) as RN,
operation
from
operation
) O on U.RN = O.RN
Edit: row_number with newid() works, so removed the extra derived table.
Here's also SQL Fiddle to test this.

how to use join in h2 database where sum function used?

there is two table:- 1. product 2. batch
-:product table:-(Row Count=700)
code
---------
001
002
-:Batch table:-(Row Count=35000)
batchno productcode Qty
--------- ----------- -----
B0002 001 5
B0003 001 10
B0004 001 15
C0005 002 20
C0034 002 10
where batch.qty integer,product.code varchar(20),batch.product varchar(20).
This code is working in sql server 2008 but not in h2 embeded database.
every fields and its data types are same as in sql server 2008.
i want output like :-
productcode qty
----------- ----
001 30
002 30
please help .
thanks in advance.
i am using this query:- SELECT product.code,(SELECT sum(batch.qty) FROM batch WHERE batch.productcode = product.code)FROM product;

How to select a data slice for a specific date from a SQL SERVER database tables which track changes on the row level

All tables in the database has a Date column named EffectiveDate.
Data is imported into the database using a logic which detects and inserts changed records only.
Let us assume 5 imports happened between 1/1/2014 and 5/1/2014
So Table A has:
EffectiveDate id1 column1 column2
-------------- ---- -------- --------
01/01/2014 1 ABC 123
02/01/2014 1 ABC 999
05/01/2014 1 XXX 999
01/01/2014 2 CCCC 555
03/01/2014 2 CCCC 444
04/01/2014 2 DDDD 444
01/01/2014 3 xxxxx 333
and Table B has
EffectiveDate id2 column1 column2
-------------- ----- -------- --------
01/01/2014 1 ZZZZ AAAAA
03/01/2014 1 ZZZZ AABBB
01/01/2014 2 TTTT AAAAA
05/01/2014 2 TTTT AABBB
Now The task is to create 3 set of views for all tables:
The first set is to give the Effective data as of current date
The second set is to give latest data
The third set is to give the data changes after today date (just next changes not the latest)
Consideration:
All views should return only one row for each id with applicable effective date.
If effective date is not available then the maximum effective date in the table less then the requested effective date should be used.
I was able to come up with solution for the Effective and Latest views but not for the third set of views (Next changes)
Any idea how to address this?
You'll need to use the Row_Number function to get this. For each id, the first future row (whatever that means...) will have a row_number of 1.
with RowNumbers as
(select
id1,
effectivedate,
row_number() over (partition by id1 order by effectivedate) as RowNumber
from
a
where
effectivedate > getdate()
)
select
a.*
from
A
inner join RowNumbers
on a.id1 = Rownumbers.id1
and rownumbers.rownumber = 1
and a.effectivedate = rownumbers.effectivedate
SQL Fidldle

Resources