MS Access "Group by" continuous values - sql

I Have the following Access table (Primary Key = Date+Id):
Date Id Value
01/07/2011 00:10:00 5 200
01/07/2011 00:30:00 5 210
01/07/2011 00:40:00 2 458
01/07/2011 00:50:00 2 500
01/07/2011 01:00:00 4 600
01/07/2011 01:10:00 5 359
01/07/2011 01:20:00 5 360
01/07/2011 01:30:00 5 370
01/07/2011 01:40:00 5 380
Of course, the query "SELECT Id, MAX(Value) FROM DATAS GROUP BY Id;" returns:
Id Max
2 500
4 600
5 380
But is it possible in MS Access to have a query which groups by "sequences" of Id?
Expected result:
Id Max
5 210
2 500
4 600
5 380

There is no easy way to solve your problem. Here is a workaround.
declare #t table(date datetime, id int, value int)
insert #t values('01/07/2011 00:10:00',5,200)
insert #t values('01/07/2011 00:30:00',5,210)
insert #t values('01/07/2011 00:40:00',2,458)
insert #t values('01/07/2011 00:50:00',2,500)
insert #t values('01/07/2011 01:00:00',4,600)
insert #t values('01/07/2011 01:10:00',5,359)
insert #t values('01/07/2011 01:20:00',5,360)
insert #t values('01/07/2011 01:30:00',5,370)
insert #t values('01/07/2011 01:40:00',5,380)
;with a as
(
select date, id, value, (select count(*) from #t where t.date > date) rn
from #t t
), b as
(
select a.date, a.id, a.value, coalesce(cast(b.id - a.id as bit),1) d
from a left join a b on a.rn -1 = b.rn
), c as
(
select date,id, value, (select sum(d) from b b2 where date <=b.date) e from b
)
select id, max(value) max
from c group by id, e
Result:
id max
----- ---
5 210
2 500
4 600
5 380

Related

Apply Sequence based on unique_id

I have a table:
table1
unique_id col_id val_id
1 100 a
1 101 b
1 102 c
1 103 d
2 106 a
2 106 b
2 104 c
2 103 d
I want to use a sequence to assign it for each unique_id.
I wrote the following which doesn't seem to work:
SELECT
my_seq.NEXTVAL over
(
PARTITION BY a.unique_id ORDER by a.unique_id) AS rec_i,
a.* FROM table1
a;
The output would be:
unique_id col_id val_id rec_i
1 100 a 123
1 101 b 123
1 102 c 123
1 103 d 123
2 106 a 124
2 106 b 124
2 104 c 124
2 103 d 124
How can I make it work?
Try this:
-- data preparation
create table tt_table (unique_id number, col_id number, val_id varchar2(1));
insert into tt_table values(1,100,'a');
insert into tt_table values(1,101,'b');
insert into tt_table values(1,102,'c');
insert into tt_table values(1,103,'d');
insert into tt_table values(2,106,'a');
insert into tt_table values(2,104,'b');
insert into tt_table values(2,103,'c');
insert into tt_table values(2,103,'d');
-- creating function
CREATE OR REPLACE FUNCTION GET_SEQ RETURN NUMBER AS
BEGIN
RETURN TEJASH_SEQ.NEXTVAL;
END GET_SEQ;
/
--
-- actual query
--
WITH T2 AS (
SELECT /*+ materialize */
UNIQUE_ID,
GET_SEQ SEQ_VALUE
FROM
(
SELECT DISTINCT
UNIQUE_ID
FROM
TT_TABLE
) T2IN
)
SELECT
T1.UNIQUE_ID,
T1.COL_ID,
T1.VAL_ID,
T2.SEQ_VALUE
FROM
TT_TABLE T1,
T2
WHERE
T1.UNIQUE_ID = T2.UNIQUE_ID
ORDER BY
T1.UNIQUE_ID;
Hope it is helpful.

Order by clause not give correct result my query is

This is the query
SELECT `properties`.`id` AS `propertyIds` , `properties_field_values`.`property_type_section_field_value` AS `price`
FROM `properties`
INNER JOIN `properties_field_values` ON `properties_field_values`.`property_id` = `properties`.`id`
INNER JOIN `property_type_section_fields` ON `property_type_section_fields`.`id` = `properties_field_values`.`property_type_section_field_id`
WHERE (
`property_type_section_fields`.`field_identifier` = 'basic_price'
)
AND EXISTS (
SELECT 1
FROM `property_availaibility`
INNER JOIN `property_availaibility_dates` ON `property_availaibility_dates`.`property_availaibility_id` = `property_availaibility`.`id`
WHERE property_availaibility.property_id = properties.id
)
AND (
`properties`.`property_type_id` =1
)
ORDER BY `price` DESC
LIMIT 0 , 30
The current output is
15 9500
13 850
4 700
5 500
6 300
1 2500
20 2300
16 2000
14 1800
11 1600
12 1550
3 1500
2 1000
What i want
15 9500
1 2500
20 2300
16 2000
14 1800
11 1600
12 1550
3 1500
2 1000
13 850
4 700
5 500
6 300
Here is a example that sorts correctly using your expected values:
DECLARE #temp TABLE ( id int, price varchar(100))
INSERT INTO #temp VALUES
(15, '9500')
,(13, '850')
,(4, '700')
,(5, '500')
,(6, '300')
,(1, '2500')
,(20, '2300')
,(16, '2000')
,(14, '1800')
,(11, '1600')
,(12, '1550')
,(3, '1500')
,(2, '1000')
SELECT *
FROM #temp ORDER BY price DESC --ordering as varchar
SELECT id, CAST(price as int) AS price --ordered as decimal
FROM #temp ORDER BY price DESC
As others have mentioned the
properties_field_values.property_type_section_field_value datatype is string, so you need to either change the datatype in the table or CAST the value in the select to an int:
SELECT
...
CAST(properties_field_values.property_type_section_field_value AS int) AS price
FROM
...
)
ORDER BY ...

Get two records per user id sql query

I am getting data
1 34 abc5
1 24 abc3
1 12 abc2
1 24 abc1
1 34 abc6
1 34 abc76
1 24 ab1c243
1 24 abc243
1 34 abc243
1 34 abc243
from my query .. is there any way to get output like this
my query
SELECT * FROM table2
WHERE (abc2 IN (SELECT * FROM table3 AS f INNER JOIN
table1 AS u ON u.id_usr = f.userLogedin_id
WHERE (u.id_usr = '13'))) AND (publish_status = '3')
ORDER BY guser_ID
1 34 abc5
1 34 abc6
1 24 abc3
1 24 abc1
1 12 abc2
i.e. orderby desc and limit to 2 per unique user .. in this case 34, 24 and 12 are unique user
try this..
with cte as
(
select row_number() over (partition by <col2> order by <col2> desc) as id, col1,col2,col3 from <tablename>
)
select * from cte where id<=2
declare #t table (id int,value int,name varchar(10))
insert into #t (id,value,name)values (1,34,'abc5')
insert into #t (id,value,name)values (1,24,'abc3')
insert into #t (id,value,name)values (1,12,'abc2')
insert into #t (id,value,name)values (1,24,'abc1')
insert into #t (id,value,name)values (1,34,'abc6')
insert into #t (id,value,name)values (1,34,'abc76')
insert into #t (id,value,name)values (1,24,'ab1c243')
insert into #t (id,value,name)values (1,24,'abc243')
insert into #t (id,value,name)values (1,34,'abc243')
insert into #t (id,value,name)values (1,34,'abc243')
SELECT t.*
FROM (
SELECT DISTINCT value
FROM #t
) tt
CROSS APPLY
(
SELECT TOP 2 *
FROM #t t
WHERE t.value = tt.value
ORDER BY
1 DESC
) t

Row_Number simulation in Sql server 2000

I have a sample input table as
Declare #input TABLE(Name VARCHAR(8))
INSERT INTO #input(Name) values('Aryan')
INSERT INTO #input(Name) values('Aryan')
INSERT INTO #input(Name) values('Joseph')
INSERT INTO #input(Name) values('Vicky')
INSERT INTO #input(Name) values('Jaesmin')
INSERT INTO #input(Name) values('Aryan')
INSERT INTO #input(Name) values('Jaesmin')
INSERT INTO #input(Name) values('Vicky')
INSERT INTO #input(Name) values('Padukon')
INSERT INTO #input(Name) values('Aryan')
INSERT INTO #input(Name) values('Jaesmin')
INSERT INTO #input(Name) values('Vick')
INSERT INTO #input(Name) values('Padukon')
INSERT INTO #input(Name) values('Joseph')
INSERT INTO #input(Name) values('Marya')
INSERT INTO #input(Name) values('Vicky')
Also I have a tally table as under
declare #t table(n int)
insert into #t select 1 union all select 2 union all
select 3 union all select 4 union all select 5 union all
select 6 union all select 7 union all select 8 union all
select 9 union all select 10 union all select 11 union all
select 12 union all select 13 union all select 14 union all
select 15 union all select 16 union all select 17 union all
select 18 union all select 19 union all select 20
In Sql Server 2005 if I do as
Select rn, name from (
select ROW_NUMBER()over (order by Name) as rn , * from #input) x
where rn % 2 <> 0
I get the output as
rn name
1 Aryan
3 Aryan
5 Jaesmin
7 Jaesmin
9 Joseph
11 Padukon
13 Vick
15 Vicky
Bu I am restricted to Sql server 2000. How can I get the same output?
I have tried with
SELECT name, (SELECT COUNT(*) FROM #input AS i2 WHERE i2.Name <= i1.Name) As rn
FROM #input AS i1
but the output is wrong
name rn
Aryan 4
Aryan 4
Joseph 9
Vicky 16
Jaesmin 7
Aryan 4
Jaesmin 7
Vicky 16
Padukon 12
Aryan 4
Jaesmin 7
Vick 13
Padukon 12
Joseph 9
Marya 10
Vicky 16
Declare your table variable as
Declare #input TABLE(_id int identity(1, 1), Name VARCHAR(8))
And then reqrite your query as
Select _id, name
from #input
where _id % 2 <> 0
Use this query:
SELECT t1.name, t.n
FROM
(
SELECT a.name, a.c, (SELECT COUNT(*) FROM #input AS i2 WHERE i2.Name <= a.Name) [rn]
FROM
(
SELECT i.name, count(*) c
FROM #input i
GROUP BY i.name
)a
)t1
JOIN #t t ON t.n <= t1.rn
WHERE t.n > t1.rn - t1.c
It produces desired output:
name n
-------- -----------
Aryan 1
Aryan 2
Aryan 3
Aryan 4
Jaesmin 5
Jaesmin 6
Jaesmin 7
Joseph 8
Joseph 9
Marya 10
Padukon 11
Padukon 12
Vick 13
Vicky 14
Vicky 15
Vicky 16

Find rows in a table where field1 is the same and field 2 is different

I have rows of a table that stores a UserID, an EnrollmentID, and other data. I want to get all records where there is more than one occurrence of a UserID and EnrollmentID.
Sample data:
serial_no userID EnrollmentID
-------------------------------
1234 100 44
1235 100 55
1236 200 33
1237 300 66
1238 400 88
1239 400 77
I'd want the following rows returned:
1234 100 44
1235 100 55
1238 400 88
1239 400 77
EDIT: To clarify, I want all rows where the userid exists with different enrollment id's
SQL Server 2005 solution
select * from
(
select *, c = COUNT(*) over (partition by userID)
from sampletable
) sq
where c > 1
or more generically
select *
from sampletable
where userid in
(
select userid
from sampletable
group by userid
having COUNT(*) > 1
)
Using this sample
create table sampletable (serial_no int, userid int, enrollmentid int)
insert sampletable select 1234 ,100 ,44
insert sampletable select 1235 ,100 ,55
insert sampletable select 1236 ,200 ,33
insert sampletable select 1237 ,300 ,66
insert sampletable select 1238 ,400 ,88
insert sampletable select 1239 ,400 ,77
Output is
serial_no userid enrollmentid
1234 100 44
1235 100 55
1238 400 88
1239 400 77
select a.serial_no, a.userID, a.EnrollmentID
from a tableA
where a.userID in (
SELECT DISTINCT a.userID
FROM tableA a, tableA b
WHERE a.userID = b.userID
AND a.EnrollmentID <> b.EnrollmentID )
SELECT a.* FROM Table1 a
INNER JOIN (
SELECT UserID FROM Table1 GROUP BY UserID HAVING COUNT(*) > 1
) b ON a.UserID = b.UserID